Index: .hgtags
===================================================================
--- .hgtags	(revision 3697)
+++ .hgtags	(revision 3472)
@@ -84,3 +84,2 @@
 25adb2b4a6d4a2266a3ffad26fff59d2adef5d7e sage-2.2
 36198dd0dfa2d81d3b1ed7a15d5323b566c92667 sage-2.2-rc1
-383ce31836f8af9625436c803e7649797dfce9dd 2.4.1.3
Index: MANIFEST.in
===================================================================
--- MANIFEST.in	(revision 3698)
+++ MANIFEST.in	(revision 3115)
@@ -1,2 +1,2 @@
-recursive-include * *.c *.h *.pyx *.pyxe *.pxd *.pxi *.cc *.txt *.tex *.i *.d 00* 
+recursive-include * *.c *.h *.pyx *.pyxe *.pxd *.pxi *.cc *.txt *.tex *.i 00* 
 include install sage-push spkg-dist spkg-install MANIFEST.in README.txt .hgignore .hg .hg/* bundle export mercurial-howto.txt pull test_changed
Index: sage/algebras/free_algebra.py
===================================================================
--- sage/algebras/free_algebra.py	(revision 4007)
+++ sage/algebras/free_algebra.py	(revision 1860)
@@ -13,26 +13,4 @@
     sage: G.base_ring()
     Free Algebra on 3 generators (x, y, z) over Integer Ring        
-
-TESTS:
-    sage: F = FreeAlgebra(GF(5),3,'x')
-    sage: F == loads(dumps(F))
-    True
-
-    sage: F.<x,y,z> = FreeAlgebra(GF(5),3)
-    sage: F == loads(dumps(F))
-    True
-
-    sage: F = FreeAlgebra(GF(5),3, ['xx', 'zba', 'Y'])
-    sage: F == loads(dumps(F))
-    True
-
-    sage: F = FreeAlgebra(GF(5),3, 'abc')
-    sage: F == loads(dumps(F))
-    True
-
-    sage: F = FreeAlgebra(FreeAlgebra(ZZ,1,'a'), 2, 'x')
-    sage: F == loads(dumps(F))
-    True
-
 """
 
@@ -220,5 +198,5 @@
             if P is self:
                 return x
-            if not (P is self.base_ring()):
+            if not (P == self.base_ring()):
                 return FreeAlgebraElement(self, x)
         # ok, not a free algebra element (or should not be viewed as one).
@@ -226,5 +204,5 @@
         R = self.base_ring()
         # coercion from free monoid
-        if isinstance(x, FreeMonoidElement) and x.parent() is F:
+        if isinstance(x, FreeMonoidElement) and x.parent() == F:
             return FreeAlgebraElement(self,{x:R(1)})
         # coercion via base ring
@@ -290,5 +268,5 @@
 
             # monoid
-            if R is self.__monoid:
+            if R == self.__monoid:
                 return self(x)
 
Index: sage/algebras/free_algebra_element.py
===================================================================
--- sage/algebras/free_algebra_element.py	(revision 4007)
+++ sage/algebras/free_algebra_element.py	(revision 1859)
@@ -3,9 +3,4 @@
 
 AUTHOR: David Kohel, 2005-09
-
-TESTS:
-    sage: R.<x,y> = FreeAlgebra(QQ,2)
-    sage: x == loads(dumps(x))
-    True
 """
 
@@ -49,5 +44,5 @@
             self.__monomial_coefficients = { x:R(1) }
         elif True:
-            self.__monomial_coefficients = dict([ (A.monoid()(e1),R(e2)) for e1,e2 in x.items()])
+            self.__monomial_coefficients = x
         else:
             raise TypeError, "Argument x (= %s) is of the wrong type."%x
Index: sage/algebras/free_algebra_quotient.py
===================================================================
--- sage/algebras/free_algebra_quotient.py	(revision 4006)
+++ sage/algebras/free_algebra_quotient.py	(revision 1840)
@@ -1,19 +1,4 @@
 """
 Free algebra quotients
-
-TESTS:
-    sage: n = 2
-    sage: A = FreeAlgebra(QQ,n,'x')
-    sage: F = A.monoid()
-    sage: i, j = F.gens()
-    sage: mons = [ F(1), i, j, i*j ]
-    sage: r = len(mons)
-    sage: M = MatrixSpace(QQ,r)
-    sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]) ]
-    sage: H2.<i,j> = A.quotient(mons,mats)
-    sage: H2 == loads(dumps(H2))
-    True
-    sage: i == loads(dumps(i))
-    True
 """
 
@@ -104,13 +89,4 @@
         ParentWithGens.__init__(self, R, names, normalize=False)
 
-    def __eq__(self,right):
-        return type(self) == type(right) and \
-               self.ngens() == right.ngens() and \
-               self.rank() == right.rank() and \
-               self.module() == right.module() and \
-               self.matrix_action() == right.matrix_action() and \
-               self.monomial_basis() == right.monomial_basis()
-    
-
     def __call__(self, x):
         if isinstance(x, FreeAlgebraQuotientElement) and x.parent() is self: 
@@ -163,10 +139,4 @@
         return self.__dim
 
-    def matrix_action(self):
-        return self.__matrix_action
-
-    def monomial_basis(self):
-        return self.__monomial_basis
-
     def rank(self):
         """
Index: sage/algebras/free_algebra_quotient_element.py
===================================================================
--- sage/algebras/free_algebra_quotient_element.py	(revision 4008)
+++ sage/algebras/free_algebra_quotient_element.py	(revision 1855)
@@ -46,11 +46,6 @@
         if isinstance(x, FreeAlgebraQuotientElement) and x.parent() is A:
             return x
-
         AlgebraElement.__init__(self, A)
         Q = self.parent()
-
-        if isinstance(x, FreeAlgebraQuotientElement) and x.parent() == Q:
-            self.__vector = Q.module()(x.vector())
-            return
         if isinstance(x, (int, long, Integer)):
             self.__vector = Q.module().gen(0) * x
@@ -109,10 +104,7 @@
             else:
                 return x
-
+        
     def vector(self):
         return self.__vector
-
-    def __cmp__(self, right):
-        return cmp(self.vector(),right.vector())
 
     def __neg__(self):
Index: sage/algebras/quaternion_algebra.py
===================================================================
--- sage/algebras/quaternion_algebra.py	(revision 4013)
+++ sage/algebras/quaternion_algebra.py	(revision 4068)
@@ -3,13 +3,4 @@
 
 AUTHOR: David Kohel, 2005-09
-
-TESTS:
-    sage: A = QuaternionAlgebra(QQ, -1,-1, names=list('ijk'))
-    sage: A == loads(dumps(A))
-    True
-    sage: i, j, k = A.gens()
-    sage: i == loads(dumps(i))
-    True
-
 """
 
@@ -40,5 +31,5 @@
 from sage.algebras.algebra_element import AlgebraElement
 from sage.algebras.free_algebra_quotient_element import FreeAlgebraQuotientElement
-from sage.algebras.quaternion_algebra_element import QuaternionAlgebraElement, QuaternionAlgebraElement_fast
+from sage.algebras.quaternion_algebra_element import QuaternionAlgebraElement
 
 import weakref
@@ -120,5 +111,5 @@
 _cache = {}
 
-def QuaternionAlgebra(K, a, b, names, denom=1):
+def QuaternionAlgebra(K, a, b, names=['i','j','k'], denom=1):
     """
     Return the quaternion algebra over $K$ generated by $i$, $j$, and $k$
@@ -150,4 +141,16 @@
         raise ValueError, "Base ring K (= %s) must be a field."%K
 
+    if K(2) == 0:
+        raise ValueError, "Base ring K (= %s) must be a field of characteristic different from 2."%K
+
+    try: 
+        a = K(a)
+    except TypeError:
+        raise ValueError, "Arguments a = %s and b = %s must coerce into K (= %s)."%(a,b,K)
+    try: 
+        b = K(b)
+    except TypeError:
+        raise ValueError, "Arguments a = %s and b = %s must coerce into K (= %s)."%(a,b,K)
+
     if a == 0 or b == 0:
         raise ValueError, "Arguments a = %s and b = %s must be nonzero."%(a,b)
@@ -168,7 +171,7 @@
     if K is RationalField():
         prms = ramified_primes(a,b)
-        H = QuaternionAlgebra_generic(K, prms)
+        H = QuaternionAlgebra_generic(K, [2,0,0,0], prms)
     else:
-        H = QuaternionAlgebra_generic(K)
+        H = QuaternionAlgebra_generic(K, [2,0,0,0])
     A = FreeAlgebra(K,3, names=names)
     F = A.monoid()
@@ -231,5 +234,5 @@
     vki = V([ -t13, t3, 0, t1 ]) - vik
     vjk = V([ -t23, 0, t3, t2 ]) - vkj
-    H = QuaternionAlgebra_generic(K)
+    H = QuaternionAlgebra_generic(K, [2,t1,t2,t3])
     A = FreeAlgebra(K,3, names=names)
     F = A.monoid()
@@ -254,5 +257,5 @@
     return QuaternionAlgebraWithInnerProduct(K,norms,traces,names=names)
 
-def QuaternionAlgebraWithDiscriminants(D1, D2, T, names, M=2):
+def QuaternionAlgebraWithDiscriminants(D1, D2, T, names=['i','j','k'], M=2):
     r"""
     Return the quaternion algebra over the rationals generated by $i$,
@@ -315,8 +318,9 @@
     mj = MQ([0,0,1,0, 0,0,0,1, -n2,0,t2,0, 0,-n2,0,t2])
     # N.B. mk = mi*mj
-    mk = MQ([0,0,0,1, 0,0,-n1,t1,  -n2*t1,n2,t1*t2-t12,0, -n1*n2,0,0,t1*t2-t12])
+    t3 = t1*t2-t12
+    mk = MQ([0,0,0,1, 0,0,-n1,t1,  -n2*t1,n2,t3,0, -n1*n2,0,0,t3])
     mats = [ mi, mj, mk ] 
     prms = ramified_primes_from_discs(D1,D2,T)
-    H = QuaternionAlgebra_generic(QQ, prms)
+    H = QuaternionAlgebra_generic(QQ, [2,t1,t2,t3], prms)
     A = FreeAlgebra(QQ,3, names=names)
     F = A.monoid()
@@ -327,21 +331,17 @@
 class QuaternionAlgebra_generic(FreeAlgebraQuotient):
 
-    def __init__(self, K, ramified_primes=None):
-        """
-        """
-        self.__vector_space = VectorSpace(K,4)
+    def __init__(self, K, basis_traces = None, ramified_primes=None):
+        """
+        """
         if ramified_primes != None:
-            self.__ramified_primes = ramified_primes
+            self._ramified_primes = ramified_primes
+        if basis_traces != None:
+	    self._basis_traces = basis_traces
         
     def __call__(self, x):
-        if hasattr(self, 'discriminants'):
-            if isinstance(x, QuaternionAlgebraElement_fast) and x.parent() is self: 
-                return x
-            return QuaternionAlgebraElement_fast(self,x)
-        else:
-            if isinstance(x, QuaternionAlgebraElement) and x.parent() is self: 
-                return x
-            return QuaternionAlgebraElement(self,x)
-        
+        if isinstance(x, QuaternionAlgebraElement) and x.parent() is self: 
+            return x
+        return QuaternionAlgebraElement(self,x)
+
     def __repr__(self):
         return "Quaternion algebra with generators %s over %s"%(
@@ -366,21 +366,22 @@
 
     def gram_matrix(self):
-        V = self.__vector_space
-        if not V._FreeModule_generic__inner_product_is_dot_product:
-            return V.inner_product_matrix()
-        K = self.base_ring()
-        M = MatrixSpace(K,4)(0)
-        B = self.basis()
-        for i in range(4):
-            x = B[i]
-            M[i,i] = 2*(x.reduced_norm())
-            for j in range(i+1,4):
-                y = B[j]
-                c = (x * y.conjugate()).reduced_trace()
-                M[i,j] = c
-                M[j,i] = c
-        # TODO: Make it so one can correctly set these things.
-        V._FreeModule_generic__inner_product_is_dot_product = False
-        V._FreeModule_generic__inner_product_matrix = M
+        """
+	The Gram matrix of the inner product determined by the norm.
+        """
+        try: 
+            M = self.__vector_space.inner_product_matrix()
+        except:	
+            K = self.base_ring()
+            M = MatrixSpace(K,4)(0)
+            B = self.basis()
+            for i in range(4):
+	        x = B[i]
+                M[i,i] = 2*(x.reduced_norm())
+                for j in range(i+1,4):
+                    y = B[j]
+                    c = (x * y.conjugate()).reduced_trace()
+                    M[i,j] = c
+                    M[j,i] = c
+            self.__vector_space = VectorSpace(K,4,inner_product_matrix = M)
         return M
         
@@ -397,10 +398,7 @@
         return False
     
-    def _set_ramified_primes(self, prms):
-        self.__ramified_primes = prms
-
     def ramified_primes(self):
         try:
-            return self.__ramified_primes
+            return self._ramified_primes
         except:
             raise AttributeError, "Ramified primes have not been computed."
@@ -411,21 +409,9 @@
 
     def vector_space(self):
-        V = self.__vector_space
         try:
-            _ = V._FreeModule_generic__inner_product_matrix
+            V = self.__vector_space
         except:
-            V._FreeModule_generic__inner_product_matrix = self.gram_matrix()
-        return self.__vector_space
-
-
-def QuaternionAlgebra_fast(K, a, b, names="ijk"):
-    H = QuaternionAlgebra(K, a, b, names)
-    H.discriminants = (a,b)
-    return H
-
-class QuaternionAlgebra_faster(QuaternionAlgebra_generic):
-    
-    def __call__(self, x):
-        if isinstance(x, QuaternionAlgebraElement_fast) and x.parent() is self: 
-            return x
-        return QuaternionAlgebraElement_fast(self,x)
+            M = self.gram_matrix() # induces construction of V
+            V = self.__vector_space
+        return V
+
Index: sage/algebras/quaternion_algebra_element.py
===================================================================
--- sage/algebras/quaternion_algebra_element.py	(revision 3727)
+++ sage/algebras/quaternion_algebra_element.py	(revision 1859)
@@ -37,5 +37,5 @@
     
     def conjugate(self):
-        return self.parent()(self.reduced_trace()) - self        
+        return self.parent()(self.reduced_trace()) - self
 	
     def reduced_trace(self):
@@ -96,36 +96,2 @@
 
     minimal_polynomial = minpoly
-    
-
-class QuaternionAlgebraElement_fast(QuaternionAlgebraElement):
-
-    def __init__(self, H, x):
-        FreeAlgebraQuotientElement.__init__(self, H, x)
-        if isinstance(x, list):
-            self._list = list(self.vector())
-        else:
-            self._list = x
-
-    def _add_(self, other):
-        return QuaternionAlgebraElement_fast(self.parent(), [self._list[i] + other._list[i] for i in range(4)])
-	
-    def _sub_(self, other):
-        return QuaternionAlgebraElement_fast(self.parent(), [self._list[i] - other._list[i] for i in range(4)])
-        
-    def _neg_(self, other):
-        return QuaternionAlgebraElement_fast(self.parent(), [-r for r in self._list])
-
-    def _mul_(self, other):
-        d1, d2 = self.parent().discriminants
-        a = self._list
-        b = other._list
-        return QuaternionAlgebraElement_fast(self.parent(), 
-            [a[0]*b[0] + d1*a[1]*b[1] + d2*a[2]*b[2] - d1*d2*a[3]*b[3],
-             a[0]*b[1] +    a[1]*b[0] + d2*a[3]*b[1] -    d2*a[2]*b[3],
-             a[0]*b[2] +    a[2]*b[0] + d1*a[1]*b[3] -    d1*a[3]*b[1],
-             a[0]*b[3] +    a[3]*b[0] +    a[1]*b[2] -       a[2]*b[1]])
-        
-    def conjugate(self):
-        return QuaternionAlgebraElement_fast(self.parent(), [self._list[0], -self._list[1], -self._list[2], -self._list[3]])
-
-
Index: sage/all.py
===================================================================
--- sage/all.py	(revision 4016)
+++ sage/all.py	(revision 3634)
@@ -30,11 +30,17 @@
 import os, sys
 
-if not os.environ.has_key('SAGE_ROOT'):
-    raise RuntimeError, "To use the SAGE libraries, set the environment variable SAGE_ROOT to the SAGE build directory and LD_LIBRARY_PATH to $SAGE_ROOT/local/lib"
- 
 if sys.version_info[:2] < (2, 5):
     print >>sys.stderr, "SAGE requires Python 2.5 or newer"
     sys.exit(1)
 
+try:
+    _l = '%s/local/lib'%os.environ['SAGE_ROOT']
+    if os.environ.has_key('LD_LIBRARY_PATH'):
+        if not _l in os.environ['LD_LIBRARY_PATH']:
+            raise KeyError
+    del _l
+except KeyError, msg:
+    raise RuntimeError, "To use the SAGE libraries, set the environment variable SAGE_ROOT to the SAGE build directory and LD_LIBRARY_PATH to $SAGE_ROOT/local/lib"
+ 
     
 ###################################################################
@@ -71,5 +77,5 @@
 from sage.interfaces.all import *
 from sage.functions.all  import *
-from sage.calculus.all   import *
+#from sage.calculus.all   import *
 from sage.server.all     import *
 from sage.dsage.all      import *
@@ -114,4 +120,5 @@
 # very useful 2-letter shortcuts
 CC = ComplexField()
+I = CC.gen(0)
 QQ = RationalField()
 RR = RealField()  # default real field
@@ -135,5 +142,5 @@
 
 oo = infinity
-#x = PolynomialRing(QQ,'x').gen()
+x = PolynomialRing(QQ,'x').gen()
 
 # grab signal handling back from PARI or other C libraries
Index: sage/calculus/all.py
===================================================================
--- sage/calculus/all.py	(revision 4063)
+++ sage/calculus/all.py	(revision 2327)
@@ -1,78 +1,7 @@
-from equations import SymbolicEquation, forget, assume, assumptions, solve
-
-from calculus import (SymbolicExpressionRing,
-                      is_SymbolicExpressionRing,
-                      is_SymbolicExpression,
-                      CallableSymbolicExpressionRing,
-                      is_CallableSymbolicExpressionRing,
-                      is_CallableSymbolicExpression,
-                      SR,
-                      sin, cos, sec, tan, log, erf, sqrt, asin, acos, atan,
-                      tanh, sinh, cosh, coth, sech, csch, ln,
-                      ceil, floor, 
-                      abs_symbolic, exp,
-                      is_SymbolicExpression,
-                      is_SymbolicExpressionRing)
+from calculus import (SER,
+                      var,
+                      sin, cos, sec,
+                      x, y, z, w, t)
 
 
-from functional import (diff, derivative,
-                        laplace, inverse_laplace,
-                        expand,
-                        integrate, limit, lim,
-                        taylor, simplify)
-
-from var import (var, function)
-
-from predefined import (a,
-                      b,
-                      c,
-                      d,
-                      f,
-                      g,
-                      h,
-                      i,
-                      j,
-                      k,
-                      l,
-                      m,
-                      n,
-                      o,
-                      p,
-                      q,
-                      r,
-                      s,
-                      t,
-                      u,
-                      v,
-                      w,
-                      x,
-                      y,
-                      z,
-                      A,
-                      B,
-                      C,
-                      D,
-                      E,
-                      F,
-                      G,
-                      H,
-                      J,
-                      K,
-                      L,
-                      M,
-                      N,
-                      P,
-                      Q,
-                      R,
-                      S,
-                      T,
-                      U,
-                      V,
-                      W,
-                      X,
-                      Y,
-                      Z)
-
-def symbolic_expression(x):
-    return SR(x)
-
+from functional import diff
Index: sage/calculus/calculus.py
===================================================================
--- sage/calculus/calculus.py	(revision 4065)
+++ sage/calculus/calculus.py	(revision 2630)
@@ -1,186 +1,9 @@
-r"""
-Symbolic Computation.
-
-AUTHORS:
-    Bobby Moretti and William Stein: 2006--2007
-
-The \sage calculus module is loosely based on the \sage Enhahcement Proposal
-found at: http://www.sagemath.org:9001/CalculusSEP.
-
-EXAMPLES:
-
-    The basic units of the calculus package are symbolic expressions
-    which are elements of the symbolic expression ring (SR). There are
-    many subclasses of SymbolicExpression. The most basic of these is
-    the formal indeterminate class, SymbolicVariable. To create a
-    SymbolicVariable object in \sage, use the var() method, whose
-    argument is the text of that variable.  Note that \sage is
-    intelligent about {\latex}ing variable names.
-
-        sage: x1 = var('x1'); x1
-        x1
-        sage: latex(x1)
-        \mbox{x}_{1}
-        sage: theta = var('theta'); theta
-        theta
-        sage: latex(theta)
-        \theta
-
-    \sage predefines upper and lowercase letters as global
-    indeterminates. Thus the following works:
-        sage: x^2
-        x^2
-        sage: type(x)
-        <class 'sage.calculus.calculus.SymbolicVariable'>
-
-    More complicated expressions in SAGE can be built up using
-    ordinary arithmetic. The following are valid, and follow the rules
-    of Python arithmetic: (The '=' operator represents assignment, and
-    not equality)
-        sage: f = x + y + z/(2*sin(y*z/55))
-        sage: g = f^f; g
-        (z/(2*sin(y*z/55)) + y + x)^(z/(2*sin(y*z/55)) + y + x)
-
-    Differentiation and integration are available, but behind the
-    scenes through maxima:
-
-        sage: f = sin(x)/cos(2*y)
-        sage: f.derivative(y)
-        2*sin(x)*sin(2*y)/(cos(2*y)^2)
-        sage: g = f.integral(x); g
-        -cos(x)/(cos(2*y))
-
-    Note that these methods require an explicit variable name. If none
-    is given, \sage will try to find one for you.
-        sage: f = sin(x); f.derivative()
-        cos(x)
-
-    However when this is ambiguous, \sage will raise an exception:
-        sage: f = sin(x+y); f.derivative()
-        Traceback (most recent call last):
-        ...
-        ValueError: must supply an explicit variable for an expression containing more than one variable
-
-    Substitution works similarly. We can substitute with a python dict:
-        sage: f = sin(x*y - z)
-        sage: f({x: t, y: z})
-        sin(t*z - z)
-    
-    Also we can substitute with keywords:
-        sage: f = sin(x*y - z)
-        sage: f(x = t, y = z)
-        sin(t*z - z)
-
-    If there is no ambiguity of variable names, we don't have to specify them:
-        sage: f = sin(x)
-        sage: f(y)
-        sin(y)
-        sage: f(pi)
-        0
-
-    However if there is ambiguity, we must explicitly state what
-    variables we're substituting for:
-    
-        sage: f = sin(2*pi*x/y)
-        sage: f(4)
-        sin(8*pi/y)
-
-    We can also make CallableSymbolicExpressions, which is a SymbolicExpression
-    that are functions of variables in a fixed order. Each
-    SymbolicExpression has a function() method used to create a
-    CallableSymbolicExpression.
-    
-        sage: u = log((2-x)/(y+5))
-        sage: f = u.function(x, y); f
-        (x, y) |--> log((2 - x)/(y + 5))
-
-    There is an easier way of creating a CallableSymbolicExpression, which
-    relies on the \sage preparser.
-    
-        sage: f(x,y) = log(x)*cos(y); f
-        (x, y) |--> log(x)*cos(y)
-
-    Then we have fixed an order of variables and there is no ambiguity
-    substituting or evaluating:
-    
-        sage: f(x,y) = log((2-x)/(y+5))
-        sage: f(7,t)
-        log(-5/(t + 5))
-
-    Some further examples:
-    
-        sage: f = 5*sin(x)
-        sage: f
-        5*sin(x)
-        sage: f(2)
-        5*sin(2)
-        sage: f(pi)
-        0
-        sage: float(f(pi))             # random low order bits
-        6.1232339957367663e-16
-
-COERCION EXAMPLES:
-
-We coerce various symbolic expressions into the complex numbers:
-
-    sage: CC(I)
-    1.00000000000000*I
-    sage: CC(2*I)
-    2.00000000000000*I
-    sage: ComplexField(200)(2*I)
-    2.0000000000000000000000000000000000000000000000000000000000*I
-    sage: ComplexField(200)(sin(I))
-    1.1752011936438014568823818505956008151557179813340958702296*I
-    sage: f = sin(I) + cos(I/2); f
-    I*sinh(1) + cosh(1/2)
-    sage: CC(f)
-    1.12762596520638 + 1.17520119364380*I
-    sage: ComplexField(200)(f)
-    1.1276259652063807852262251614026720125478471180986674836290 + 1.1752011936438014568823818505956008151557179813340958702296*I
-    sage: ComplexField(100)(f)
-    1.1276259652063807852262251614 + 1.1752011936438014568823818506*I
-
-We illustrate construction of an inverse sum where each denominator
-has a new variable name:
-    sage: f = sum(1/var('n%s'%i)^i for i in range(10))
-    sage: print f
-                 1     1     1     1     1     1     1     1    1
-                --- + --- + --- + --- + --- + --- + --- + --- + -- + 1
-                  9     8     7     6     5     4     3     2   n1
-                n9    n8    n7    n6    n5    n4    n3    n2
-                
-Note that after calling var, the variables are immediately available for use:
-    sage: (n1 + n2)^5
-    (n2 + n1)^5
-
-We can, of course, substitute:
-    sage: print f(n9=9,n7=n6)
-            1     1     1     1     1     1     1    1    387420490
-           --- + --- + --- + --- + --- + --- + --- + -- + ---------
-             8     6     7     5     4     3     2   n1   387420489
-           n8    n6    n6    n5    n4    n3    n2
-
-TESTS:
-We test pickling:
-    sage: f = -sqrt(pi)*(x^3 + sin(x/cos(y)))
-    sage: bool(loads(dumps(f)) == f)
-    True
-
-Substitution:
-    sage: f = x
-    sage: f(x=5)
-    5
-
-"""
-
-import weakref
+"""nodoctest"""
 
 from sage.rings.all import (CommutativeRing, RealField, is_Polynomial,
-                            is_MPolynomial, is_MPolynomialRing,
                             is_RealNumber, is_ComplexNumber, RR,
-                            Integer, Rational, CC,
-                            PolynomialRing)
-
-from sage.structure.element import RingElement, is_Element
+                            Integer, Rational, CC)
+#import sage.rings.rational
+from sage.structure.element import RingElement
 from sage.structure.parent_base import ParentWithBase
 
@@ -194,62 +17,12 @@
 from sage.misc.sage_eval import sage_eval
 
-from sage.calculus.equations import SymbolicEquation
-from sage.rings.real_mpfr import RealNumber
-from sage.rings.complex_number import ComplexNumber
-from sage.rings.real_double import RealDoubleElement
-from sage.rings.complex_double import ComplexDoubleElement
-from sage.rings.real_mpfi import RealIntervalFieldElement
-from sage.rings.infinity import InfinityElement
-
-from sage.libs.pari.gen import pari, gen as PariGen
-
-from sage.rings.complex_double import ComplexDoubleElement
-
-import sage.functions.constants
-
-import math
-
-is_simplified = False
-
-infixops = {operator.add: '+',
-            operator.sub: '-', 
-            operator.mul: '*',
-            operator.div: '/',
-            operator.pow: '^'}
-
-
-def is_SymbolicExpression(x):
-    """
-    EXAMPLES:
-        sage: is_SymbolicExpression(sin(x))
-        True
-        sage: is_SymbolicExpression(2/3)
-        False
-        sage: is_SymbolicExpression(sqrt(2))
-        True
-    """
-    return isinstance(x, SymbolicExpression)
-
-def is_SymbolicExpressionRing(x):
-    """
-    EXAMPLES:
-        sage: is_SymbolicExpressionRing(QQ)
-        False
-        sage: is_SymbolicExpressionRing(SR)
-        True
-    """
-    return isinstance(x, SymbolicExpressionRing_class)
-
-
+from sage.functions.constants import Constant
+import sage.functions.constants as c
+
+# There will only ever be one instance of this class
 class SymbolicExpressionRing_class(CommutativeRing):
-    """
-    The ring of all formal symbolic expressions.
-
-    EXAMPLES:
-        sage: SR
-        Symbolic Ring
-        sage: type(SR)
-        <class 'sage.calculus.calculus.SymbolicExpressionRing_class'>
-    """
+    '''
+    A Ring of formal expressions.
+    '''
     def __init__(self):
         self._default_precision = 53 # default precision bits
@@ -257,32 +30,8 @@
 
     def __call__(self, x):
-        """
-        Coerce x into the symbolic expression ring SR.
-        
-        EXAMPLES:
-            sage: a = SR(-3/4); a
-            -3/4
-            sage: type(a)
-            <class 'sage.calculus.calculus.SymbolicConstant'>
-            sage: a.parent()
-            Symbolic Ring
-
-        If a is already in the symblic expression ring, coercing returns
-        a itself (not a copy):
-            sage: SR(a) is a
-            True
-
-        A Python complex number:
-            sage: SR(complex(2,-3))
-            2.00000000000000 - 3.00000000000000*I
-        """
-        if is_Element(x) and x.parent() is self:
-            return x
-        elif hasattr(x, '_symbolic_'):
-            return x._symbolic_(self)
         return self._coerce_impl(x)
 
     def _coerce_impl(self, x):
-        if isinstance(x, CallableSymbolicExpression):
+        if isinstance(x, CallableFunction):
             return x._expr
         elif isinstance(x, SymbolicExpression):
@@ -290,33 +39,16 @@
         elif isinstance(x, MaximaElement):
             return symbolic_expression_from_maxima_element(x)
-        elif is_Polynomial(x) or is_MPolynomial(x):
+        elif is_Polynomial(x):
             return SymbolicPolynomial(x)
-        elif isinstance(x, (RealNumber, 
-                            RealDoubleElement,
-                            RealIntervalFieldElement,
-                            float,
-                            sage.functions.constants.Constant,
-                            Integer,
-                            int,
-                            Rational,
-                            PariGen,
-                            ComplexNumber,
-                            ComplexDoubleElement,
-                            InfinityElement
-                            )):
-            return SymbolicConstant(x)
-        elif isinstance(x, complex):
-            return evaled_symbolic_expression_from_maxima_string('%s+%%i*%s'%(x.real,x.imag))
+        elif isinstance(x, Integer):
+            return Constant_object(x)
         else:
-            raise TypeError, 'cannot coerce %s into a SymbolicExpression.'%x
-
-    def _repr_(self):
-        return 'Symbolic Ring'
-
-    def _latex_(self):
-        return 'SymbolicExpressionRing'
-
-    def var(self, x):
-        return var(x)
+            return Symbolic_object(x)
+
+    def _repr_(self):
+        return  "Ring of Symbolic Expressions"
+
+    def _latex_(self):
+        return "SymbolicExpressionRing"
 
     def characteristic(self):
@@ -329,381 +61,88 @@
         return True
 
-    def is_exact(self):
-        return False
-
-# Define the unique symbolic expression ring.
-SR = SymbolicExpressionRing_class()
-
-# The factory function that returns the unique SR.
-def SymbolicExpressionRing():
-    """
-    Return the symbolic expression ring.
-    
-    EXAMPLES:
-        sage: SymbolicExpressionRing()
-        Symbolic Ring
-        sage: SymbolicExpressionRing() is SR
-        True
-    """
-    return SR
+# ... and here it is:
+SymbolicExpressionRing = SymbolicExpressionRing_class()
+SER = SymbolicExpressionRing
+# conversions is the dict of the form system:command
 
 class SymbolicExpression(RingElement):
     """
     A Symbolic Expression.
-
-    EXAMPLES:
-    
     """
-    def __init__(self):
-        RingElement.__init__(self, SR)
-        if is_simplified:
-            self._simp = self
-
-    def __nonzero__(self):
-        # Best to error on side of being nonzero in most cases. 
-        return not bool(self == SR.zero_element())
-
-    def __str__(self):
-        """
-        Printing an object explicitly gives ASCII art:
-
-        EXAMPLES:
-            sage: f = y^2/(y+1)^3 + x/(x-1)^3
-            sage: f
-            y^2/(y + 1)^3 + x/(x - 1)^3
-            sage: print f
-                                              2
-                                             y          x
-                                          -------- + --------
-                                                 3          3
-                                          (y + 1)    (x - 1)
-        
-        """
-        return self.display2d(onscreen=False)
-
-    def display2d(self, onscreen=True):
-        """
-        Display self using ASCII art.
-
-        INPUT:
-            onscreen -- string (optional, default True) If True,
-                displays; if False, returns string.
-
-        EXAMPLES:
-        We display a fraction:
-            sage: f = (x^3+y)/(x+3*y^2+1); f
-            (y + x^3)/(3*y^2 + x + 1)
-            sage: print f
-                                                     3
-                                                y + x
-                                             ------------
-                                                2
-                                             3 y  + x + 1
-
-        Use onscreen=False to get the 2d string:
-             sage: f.display2d(onscreen=False)
-             '\t\t\t\t\t 3\r\n\t\t\t\t    y + x\r\n         \t\t\t ------------\r\n\t\t\t\t    2\r\n\t\t\t\t 3 y  + x + 1'
-
-        ASCII art is really helps for the following integral:
-            sage: f = integral(sin(x^2)); f
-            sqrt(pi)*((sqrt(2)*I + sqrt(2))*erf((sqrt(2)*I + sqrt(2))*x/2) + (sqrt(2)*I - sqrt(2))*erf((sqrt(2)*I - sqrt(2))*x/2))/8
-            sage: print f
-                                                         (sqrt(2)  I + sqrt(2)) x
-                   sqrt( pi) ((sqrt(2)  I + sqrt(2)) erf(------------------------)
-                                                                    2
-                                                               (sqrt(2)  I - sqrt(2)) x
-                                  + (sqrt(2)  I - sqrt(2)) erf(------------------------))/8
-                                                                          2
-        """
-        s = self._maxima_().display2d(onscreen=False)
-        s = s.replace('%pi',' pi').replace('%i',' I').replace('%e', ' e')
-        if onscreen:
-            print s
-        else:
-            return s
-    
-    def is_simplified(self):
-        return hasattr(self, '_simp') and self._simp is self
-
-    def _declare_simplified(self):
-        self._simp = self
-
-    def hash(self):
-        return hash(self._repr_(simplify=False))
-
-    def plot(self, *args, **kwds):
-        from sage.plot.plot import plot
-
-        # see if the user passed a variable in.
-        if kwds.has_key('param'):
-            param = kwds['param']
-        else:
-            param = None
-            for i in range(len(args)):
-                if isinstance(args[i], SymbolicVariable):
-                    param = args[i]
-                    args = args[:i] + args[i+1:]
-                    break
-
-        F = self.simplify()
-        if isinstance(F, Symbolic_object):
-            if hasattr(F._obj, '__call__'):
-                f = lambda x: F._obj(x)
-            else:
-                y = float(F._obj)
-                f = lambda x: y
-        
-        elif param is None:
-            if isinstance(self, CallableSymbolicExpression):
-                A = self.arguments()
-                if len(A) == 0:
-                    raise ValueError, "function has no input arguments"
-                else:
-                    param = A[0]
-                f = lambda x: self(x)
-            else:
-                A = self.variables()
-                if len(A) == 0:
-                    y = float(self)
-                    f = lambda x: y
-                else:
-                    param = A[0]
-                f = self.function(param)
-        else:
-            f = self.function(param)
-        return plot(f, *args, **kwds)
-
-    def __lt__(self, right):
-        return SymbolicEquation(self, SR(right), operator.lt)
-
-    def __le__(self, right):
-        return SymbolicEquation(self, SR(right), operator.le)
-
-    def __eq__(self, right):
-        return SymbolicEquation(self, SR(right), operator.eq)
-
-    def __ne__(self, right):
-        return SymbolicEquation(self, SR(right), operator.ne)
-
-    def __ge__(self, right):
-        return SymbolicEquation(self, SR(right), operator.ge)
-
-    def __gt__(self, right):
-        return SymbolicEquation(self, SR(right), operator.gt)
+    def __init__(self, conversions={}):
+        RingElement.__init__(self, SymbolicExpressionRing)
+
+    def _maxima_(self, maxima=maxima):
+        try:
+            return self.__maxima
+        except AttributeError:
+            m = maxima(self._maxima_init_())
+            self.__maxima = m
+            return m
+
+    def _neg_(self):
+        return SymbolicArithmetic([self], operator.neg)
 
     def __cmp__(self, right):
-        """
-        Compares self and right.
-
-        This is by definition the comparison of the underlying Maxima
-        objects.
-
-        EXAMPLES:
-        These two are equal:
-            sage: cmp(e+e, e*2)
-            0
-        """
         return cmp(maxima(self), maxima(right))
-
-    def _neg_(self):
-        """
-        Return the formal negative of self.
-
-        EXAMPLES:
-            sage: -a
-            -a
-            sage: -(x+y)
-            -y - x
-        """
-        return SymbolicArithmetic([self], operator.neg)
-
-    ##################################################################
-    # Coercions to interfaces
-    ##################################################################
-    # The maxima one is special:
-    def _maxima_init_(self):
-        return self._repr_(simplify=False)
-
-
-    # The others all go through _sys_init_, which is defined below,
-    # and does all interfaces in a unified manner.
-    
-    def _axiom_init_(self):
-        return self._sys_init_('axiom')
-
-    def _gp_init_(self):
-        return self._sys_init_('pari')   # yes, gp goes through pari
-
-    def _maple_init_(self):
-        return self._sys_init_('maple')
-
-    def _magma_init_(self):
-        return '"%s"'%self.str()
-
-    def _kash_init_(self):
-        return self._sys_init_('kash')
-
-    def _macaulay2_init_(self):
-        return self._sys_init_('macaulay2')
-
-    def _mathematica_init_(self):
-        return self._sys_init_('mathematica')
-
-    def _octave_init_(self):
-        return self._sys_init_('octave')
-
-    def _pari_init_(self):
-        return self._sys_init_('pari')
-
-    def _sys_init_(self, system):
-        return repr(self)
-
-    ##################################################################
-    # These systems have no symbolic or numerical capabilities at all,
-    # really, so we always just coerce to a string
-    ##################################################################
-    def _gap_init_(self):
-        """
-        Conversion of symbolic object to GAP always results in a GAP string.
-        
-        EXAMPLES:
-            sage: gap(e+pi^2 + x^3)
-            "x^3 + pi^2 + e"
-        """
-        return '"%s"'%repr(self)
-
-    def _singular_init_(self):
-        """
-        Conversion of symbolic object to Singular always results in a Singular string.
-        
-        EXAMPLES:
-            sage: singular(e+pi^2 + x^3)
-            x^3 + pi^2 + e
-        """
-        return '"%s"'%repr(self)
-
-    ##################################################################
-    # Non-canonical coercions to compiled built-in rings and fields
-    ##################################################################
-    def __int__(self):
-        """
-        EXAMPLES:
-            sage: int(sin(2)*100)
-            90
-        """
-        try:
-            return int(repr(self))
-        except (ValueError, TypeError):
-            return int(float(self))
-
-    def __long__(self):
-        """
-        EXAMPLES:
-            sage: long(sin(2)*100)
-            90L
-        """
-        return long(int(self))
-
-    
-    def _mpfr_(self, field):
-        raise TypeError
-
-    def _complex_mpfr_field_(self, field):
-        raise TypeError
-
-    def _complex_double_(self, C):
-        raise TypeError
-
-    def _real_double_(self, R):
-        raise TypeError
-
-    def _rational_(self):
-        return Rational(repr(self))
-
-    def __abs__(self):
-        return abs_symbolic(self)
-    
-    def _integer_(self):
-        """
-        EXAMPLES:
-        
-        """
-        return Integer(repr(self))
-    
+        
     def _add_(self, right):
-        """
-        EXAMPLES:
-            sage: x + y
-            y + x
-            sage: x._add_(y)
-            y + x
-        """
-        return SymbolicArithmetic([self, right], operator.add)
+        # if we are adding a negation, instead subtract the operand of negation
+        #if isinstance(right, SymbolicArithmetic):
+        #    if right._operator is operator.neg:
+        #        return SymbolicArithmetic([self, right._operands[0]], operator.sub)
+        #elif isinstance(right, Symbolic_object) and right < 0:
+        #    return SymbolicArithmetic([self, SER(abs(right._obj))], operator.sub)
+        #else:
+            return SymbolicArithmetic([self, right], operator.add)
 
     def _sub_(self, right):
-        """
-        EXAMPLES:
-            sage: x - y
-            x - y
-        """
         return SymbolicArithmetic([self, right], operator.sub)
 
     def _mul_(self, right):
-        """
-        EXAMPLES:
-            sage: x * y
-            x*y
-        """
+        # do some simplification... pull out negatives from the operands and put it
+        # in front of this multiplication
+        #if isinstance(self, SymbolicArithmetic) and isinstance(right, SymbolicArithmetic):
+        #    if self._operator is operator.neg and right._operator is operator.neg:
+        #        s_unneg = self._operands[0]
+        #        r_unneg = right._operands[0]
+        #        return SymbolicArithmetic([s_unneg, r_unneg], operator.mul)
+        #if isinstance(self, SymbolicArithmetic):
+        #    if self._operator is operator.neg and (not isinstance(right, SymbolicArithmetic) \
+        #    or not (right._operator is operator.neg)):
+        #        s_unneg = self._operands[0]
+        #        return -SymbolicArithmetic([s_unneg, right], operator.mul)
+        #if isinstance(right, SymbolicArithmetic):
+        #    if not isinstance(self, SymbolicArithmetic) or (not (self._operator is operator.neg)) \
+        #    and right._operator is operator.neg:
+        #        r_unneg = right._operands[0]
+        #        return -SymbolicArithmetic([self, r_unneg], operator.mul)
+            
         return SymbolicArithmetic([self, right], operator.mul)
 
     def _div_(self, right):
-        """
-        EXAMPLES:
-            sage: x / y
-            x/y
-        """
+        # do some simplification... pull out negatives from the operands and put it
+        # in front of this division
+        #if isinstance(self, SymbolicArithmetic) and isinstance(right, SymbolicArithmetic):
+        #    if self._operator is operator.neg and right._operator is operator.neg:
+        #        s_unneg = self._operands[0]
+        #        r_unneg = right._operands[0]
+        #        return SymbolicArithmetic([s_unneg, r_unneg], operator.div)
+        #elif isinstance(self, SymbolicArithmetic):
+        #    if self._operator is operator.neg and (not isinstance(right, SymbolicArithmetic) \
+        #    or not (right._operator is operator.neg)):
+        #        s_unneg = self._operands[0]
+        #        return -SymbolicArithmetic([s_unneg, right], operator.div)
+        #elif isinstance(right, SymbolicArithmetic):
+        #    if not isinstance(self, SymbolicArithmetic) or (not (self._operator is operator.neg)) \
+        #    and right._operator is operator.neg:
+        #        r_unneg = right._operands[0]
+        #        return -SymbolicArithmetic([self, r_unneg], operator.div)
+
         return SymbolicArithmetic([self, right], operator.div)
 
     def __pow__(self, right):
-        """
-        EXAMPLES:
-            sage: x^(n+1)
-            x^(n + 1)
-        """
         right = self.parent()(right)
         return SymbolicArithmetic([self, right], operator.pow)
-
-    def variables(self, vars=tuple([])):
-        """
-        Return sorted list of variables that occur in the simplified
-        form of self.
-
-        OUTPUT:
-            a Python set
-            
-        EXAMPLES:
-            sage: f = x^(n+1) + sin(pi/19); f
-            x^(n + 1) + sin(pi/19)
-            sage: f.variables()
-            (n, x)
-            
-            sage: a = e^x
-            sage: a.variables()
-            (x,)            
-        """
-        return vars
-
-    def _first_variable(self):
-        try:
-            return self.__first_variable
-        except AttributeError:
-            pass
-        v = self.variables()
-        if len(v) == 0:
-            ans = var('x')
-        else:
-            ans = v[0]
-        self.__first_variable = ans
-        return ans
 
     def _has_op(self, operator):
@@ -747,166 +186,11 @@
 
 
-    def __call__(self, dict=None, **kwds):
-        return self.substitute(dict, **kwds)
-
-    def power_series(self, base_ring):
-        """
-        Return algebraic power series associated to this symbolic
-        expression, which must be a polynomial in one variable, with
-        coefficients coercible to the base ring.
-        
-        The power series is truncated one more than the degree.
-
-        EXAMPLES:
-            sage: var('theta')
-            theta
-            sage: f = theta^3 + (1/3)*theta - 17/3
-            sage: g = f.power_series(QQ); g
-            -17/3 + 1/3*theta + theta^3 + O(theta^4)
-            sage: g^3
-            -4913/27 + 289/9*theta - 17/9*theta^2 + 2602/27*theta^3 + O(theta^4)
-            sage: g.parent()
-            Power Series Ring in theta over Rational Field
-        """
-        v = self.variables()
-        if len(v) != 1:
-            raise ValueError, "self must be a polynomial in one variable but it is in the variables %s"%tuple([v])
-        f = self.polynomial(base_ring)
-        from sage.rings.all import PowerSeriesRing
-        R = PowerSeriesRing(base_ring, names=f.parent().variable_names())
-        return R(f, f.degree()+1)
-
-    def polynomial(self, base_ring):
-        r"""
-        Return self as an algebraic polynomial over the given base ring, if
-        possible.
-
-        The point of this function is that it converts purely symbolic
-        polynomials into optimized algebraic polynomials over a given
-        base ring.
-
-        WARNING: This is different from \code{self.poly(x)} which is used
-        to rewrite self as a polynomial in x.
-
-        INPUT:
-           base_ring -- a ring
-
-        EXAMPLES:
-            sage: f = x^2 -2/3*x + 1
-            sage: f.polynomial(QQ)
-            x^2 - 2/3*x + 1
-            sage: f.polynomial(GF(19))
-            x^2 + 12*x + 1
-
-            sage: f = x^2*e + x + pi/e
-            sage: f.polynomial(RDF)
-            2.71828182846*x^2 + 1.0*x + 1.15572734979
-            sage: g = f.polynomial(RR); g
-            2.71828182845905*x^2 + 1.00000000000000*x + 1.15572734979092
-            sage: g.parent()
-            Univariate Polynomial Ring in x over Real Field with 53 bits of precision            
-            sage: f.polynomial(RealField(100))
-            2.7182818284590452353602874714*x^2 + 1.0000000000000000000000000000*x + 1.1557273497909217179100931833
-            sage: f.polynomial(CDF)
-            2.71828182846*x^2 + 1.0*x + 1.15572734979
-            sage: f.polynomial(CC)
-            2.71828182845905*x^2 + 1.00000000000000*x + 1.15572734979092
-
-        We coerce a multivariate polynomial with complex symbolic coefficients:
-            sage: f = pi^3*x - y^2*e - I; f
-            -1*e*y^2 + pi^3*x - I
-            sage: f.polynomial(CDF)
-            -1.0*I + (-2.71828182846)*y^2 + 31.0062766803*x
-            sage: f.polynomial(CC)
-            -1.00000000000000*I + (-2.71828182845905)*y^2 + 31.0062766802998*x
-            sage: f.polynomial(ComplexField(70))
-            -1.0000000000000000000*I + (-2.7182818284590452354)*y^2 + 31.006276680299820175*x
-
-        Another polynomial:
-            sage: f = sum((e*I)^n*x^n for n in range(5)); f
-            e^4*x^4 - e^3*I*x^3 - e^2*x^2 + e*I*x + 1
-            sage: f.polynomial(CDF)
-            54.5981500331*x^4 + (-20.0855369232*I)*x^3 + (-7.38905609893)*x^2 + 2.71828182846*I*x + 1.0
-            sage: f.polynomial(CC)
-            54.5981500331442*x^4 + (-20.0855369231877*I)*x^3 + (-7.38905609893065)*x^2 + 2.71828182845905*I*x + 1.00000000000000
-
-        A multivariate polynomial over a finite field:
-            sage: f = (3*x^5 - 5*y^5)^7; f
-            (3*x^5 - 5*y^5)^7
-            sage: g = f.polynomial(GF(7)); g
-            2*y^35 + 3*x^35
-            sage: parent(g)
-            Polynomial Ring in x, y over Finite Field of size 7
-        """
-        vars = self.variables()
-        if len(vars) == 0:
-            vars = ['x']
-        R = PolynomialRing(base_ring, names=vars)  
-        G = R.gens()
-        V = R.variable_names()
-        return self.substitute_over_ring(
-             dict([(var(V[i]),G[i]) for i in range(len(G))]), ring=R)
-    
-    def _polynomial_(self, R):
-        """
-        Coerce this symbolic expression to a polynomial in R.
-
-        EXAMPLES:
-            sage: R = QQ[x,y,z]
-            sage: R(x^2 + y)
-            y + x^2
-            sage: R = QQ[w]
-            sage: R(w^3 + w + 1)
-            w^3 + w + 1
-            sage: R = GF(7)[z]
-            sage: R(z^3 + 10*z)
-            z^3 + 3*z
-
-        NOTE: If the base ring of the polynomial ring is the symbolic
-        ring, then a constant polynomial is always returned.
-            sage: R = SR[x]
-            sage: a = R(sqrt(2) + x^3 + y)
-            sage: a
-            y + x^3 + sqrt(2)
-            sage: type(a)
-            <class 'sage.rings.polynomial_element_generic.Polynomial_generic_dense'>
-            sage: a.degree()
-            0
-
-        We coerce to a double precision complex polynomial ring:
-            sage: f = e*x^3 + pi*y^3 + sqrt(2) + I; f
-            pi*y^3 + e*x^3 + I + sqrt(2)
-            sage: R = CDF[x,y]
-            sage: R(f)
-            1.41421356237 + 1.0*I + 3.14159265359*y^3 + 2.71828182846*x^3
-
-        We coerce to a higher-precision polynomial ring
-            sage: R = ComplexField(100)[x,y]
-            sage: R(f)
-            1.4142135623730950066967437806 + 1.0000000000000000000000000000*I + 3.1415926535897932384626433833*y^3 + 2.7182818284590452353602874714*x^3
-            
-        """
-        vars = self.variables()
-        B = R.base_ring()
-        if B == SR:
-            if is_MPolynomialRing(R):
-                return R({tuple([0]*R.ngens()):self})
-            else:
-                return R([self])
-        G = R.gens()
-        sub = []
-        for v in vars:
-            r = repr(v)
-            for g in G:
-                if repr(g) == r:
-                    sub.append((v,g))
-        if len(sub) == 0:
-            return R(B(self))
-        return self.substitute_over_ring(dict(sub), ring=R)
+    def __call__(self, **kwds):
+        return self.substitute(**kwds)
 
     def function(self, *args):
         """
-        Return a CallableSymbolicExpression, fixing a variable order
-        to be the order of args.
+        Return a CallableFunction, fixing a variable order to be the order of
+        args.
 
         EXAMPLES:
@@ -914,37 +198,11 @@
            sage: g = u.function(x,y)
            sage: g(x,y)
-           x*cos(y) + sin(x)
+           sin(x) + x*cos(y)
            sage: g(t,z)
-           t*cos(z) + sin(t)
-           sage: g(x^2, x^y)
-           x^2*cos(x^y) + sin(x^2)
-
-            sage: f = (x^2 + sin(a*w)).function(a,x,w); f
-            (a, x, w) |--> x^2 + sin(a*w)
-            sage: f(1,2,3)
-            sin(3) + 4
-
-        Using the function method we can obtain the above function f,
-        but viewed as a function of different variables:
-            sage: h = f.function(w,a); h
-            (w, a) |--> x^2 + sin(a*w)
-
-        This notation also works:
-            sage: h(w,a) = f
-            sage: h
-            (w, a) |--> x^2 + sin(a*w)
-
-        You can even make a symbolic expression $f$ into a function by
-        writing \code{f(x,y) = f}:
-            sage: f = x^n + y^n; f
-            y^n + x^n
-            sage: f(x,y) = f
-            sage: f
-            (x, y) |--> y^n + x^n
-            sage: f(2,3)
-            3^n + 2^n
-        """
-        R = CallableSymbolicExpressionRing(args)
-        return R(self)
+           sin(t) + t*cos(z)
+           sage: g(x^2, log(y))
+           sin(x^2) + x^2*cos(log(y))
+        """
+        return CallableFunction(self, args)
 
 
@@ -967,24 +225,11 @@
         # check each time
         s = ""
-        # see if we can implicitly supply a variable name
-        try:
-            a = args[0]
-        except IndexError:
-            # if there were NO arguments, try assuming 
-            a = 1
-        if a is None or isinstance(a, (int, long, Integer)):
-            vars = self.variables()
-            if len(vars) == 1:
-                s = "%s, %s" % (vars[0], a)
-            else:
-                raise ValueError, "must supply an explicit variable for an " +\
-                                "expression containing more than one variable"
         for i in range(len(args)):
             if isinstance(args[i], SymbolicVariable):
-                s = s + '%s, ' %repr(args[i])
+                s = s + '%s, ' %str(args[i])
                 # check to see if this is followed by an integer
                 try:
                     if isinstance(args[i+1], (int, long, Integer)):
-                        s = s + '%s, ' %repr(args[i+1])
+                        s = s + '%s, ' %str(args[i+1])
                     else:
                         s = s + '1, '
@@ -1008,582 +253,19 @@
         f = self.parent()(t)
         return f
-
-    differentiate = derivative
-    diff = derivative
         
     
     ###################################################################
-    # Taylor series
-    ###################################################################
-    def taylor(self, v, a, n):
-        """
-        Expands self in a truncated Taylor or Laurent series in the
-        variable v around the point a, containing terms through $(x - a)^n$.
-
-        INPUT:
-            v -- variable
-            a -- number
-            n -- integer
-
+    # integral
+    ###################################################################
+    def integral(self, v):
+        """
         EXAMPLES:
-            sage: taylor(a*log(z), z, 2, 3)
-            log(2)*a + a*(z - 2)/2 - (a*(z - 2)^2/8) + a*(z - 2)^3/24
-            sage: taylor(sqrt (sin(x) + a*x + 1), x, 0, 3)
-            1 + (a + 1)*x/2 - ((a^2 + 2*a + 1)*x^2/8) + (3*a^3 + 9*a^2 + 9*a - 1)*x^3/48
-            sage: taylor (sqrt (x + 1), x, 0, 5)
-            1 + x/2 - (x^2/8) + x^3/16 - (5*x^4/128) + 7*x^5/256
-            sage: taylor (1/log (x + 1), x, 0, 3)
-            1/x + 1/2 - (x/12) + x^2/24 - (19*x^3/720)
-            sage: taylor (cos(x) - sec(x), x, 0, 5)
-            -x^2 - (x^4/6)
-            sage: taylor ((cos(x) - sec(x))^3, x, 0, 9)
-            -x^6 - (x^8/2)
-            sage: taylor (1/(cos(x) - sec(x))^3, x, 0, 5)
-            -1/x^6 + 1/(2*x^4) + 11/(120*x^2) - 347/15120 - (6767*x^2/604800) - (15377*x^4/7983360)
-        """
-        v = var(v)
-        l = self._maxima_().taylor(v, SR(a), Integer(n))
-        return self.parent()(l)
-
-    ###################################################################
-    # limits
-    ###################################################################
-    def limit(self, dir=None, **argv):
-        """
-        Return the limit as the variable v approaches a from the
-        given direction.
-
-        \begin{verbatim}
-        expr.limit(x = a)
-        expr.limit(x = a, dir='above')
-        \end{verbatim}
-
-        INPUT:
-            dir -- (default: None); dir may have the value `plus' (or 'above')
-                   for a limit from above, `minus' (or 'below') for a limit from
-                   below, or may be omitted (implying a two-sided
-                   limit is to be computed).
-            **argv -- 1 named parameter
-
-        NOTE: Output it may also use `und' (undefined), `ind'
-        (indefinite but bounded), and `infinity' (complex infinity).
-
-        EXAMPLES:
-            sage: f = (1+1/x)^x
-            sage: f.limit(x = oo)
-            e
-            sage: f.limit(x = 5)
-            7776/3125
-            sage: f.limit(x = 1.2)
-            2.069615754672029
-            sage: f.limit(x = I)
-            e^(I*log(1 - I))
-            sage: f(1.2)
-            2.069615754672029
-            sage: f(I)
-            (1 - I)^I
-            sage: CDF(f(I))
-            2.06287223508 + 0.74500706218*I
-            sage: CDF(f.limit(x = I))
-            2.06287223508 + 0.74500706218*I
-
-        More examples:
-            sage: limit(x*log(x), x = 0, dir='above')
-            0
-            sage: lim((x+1)^(1/x),x = 0)
-            e
-            sage: lim(e^x/x, x = oo)
-            +Infinity
-            sage: lim(e^x/x, x = -oo)
-            0
-            sage: lim(-e^x/x, x = oo)
-            -Infinity
-
-        The following means "indefinite but bounded":
-            sage: lim(sin(1/x), x = 0)
-            ind            
-        """
-        if len(argv) != 1:
-            raise ValueError, "call the limit function like this, e.g. limit(expr, x=2)."
-        else:
-            k = argv.keys()[0]
-            v = var(k, create=False)
-            a = argv[k]
-        if dir is None:
-            l = self._maxima_().limit(v, a)
-        elif dir == 'plus' or dir == 'above':
-            l = self._maxima_().limit(v, a, 'plus')
-        elif dir == 'minus' or dir == 'below':
-            l = self._maxima_().limit(v, a, 'minus')
-        else:
-            raise ValueError, "dir must be one of 'plus' or 'minus'"
-        return self.parent()(l)
-
-    ###################################################################
-    # Laplace transform
-    ###################################################################
-    def laplace(self, t, s):
-        r"""
-        Attempts to compute and return the Laplace transform of self
-        with respect to the variable t and transform parameter s.  If
-        Laplace cannot find a solution, a formal function is returned.
-
-        The function that is returned maybe be viewed as a function of s.
-
-        DEFINITION:
-        The Laplace transform of a function $f(t)$, defined for all
-        real numbers $t \geq 0$, is the function $F(s)$ defined by
-        $$
-             F(s) = \int_{0}^{\infty} e^{-st} f(t) dt.
-        $$
-
-        EXAMPLES:
-        We compute a few Laplace transforms:
-            sage: sin(x).laplace(x, s)
-            1/(s^2 + 1)
-            sage: (z + exp(x)).laplace(x, s)
-            z/s + 1/(s - 1)
-
-        We do a formal calculation:
-            sage: f = function('f', x)
-            sage: g = f.diff(x); g
-            diff(f(x), x, 1)
-            sage: g.laplace(x, s)
-            s*laplace(f(x), x, s) - f(0)        
-        
-        """
-        return self.parent()(self._maxima_().laplace(var(t), var(s)))
-
-    def inverse_laplace(self, t, s):
-        r"""
-        Attempts to compute the inverse Laplace transform of self with
-        respect to the variable t and transform parameter s.  If
-        Laplace cannot find a solution, a formal function is returned.
-
-        The function that is returned maybe be viewed as a function of s.
-
-
-        DEFINITION:
-        The inverse Laplace transform of a function $F(s)$,
-        is the function $f(t)$ defined by
-        $$
-             F(s) = \frac{1}{2\pi i} \int_{\gamma-i\infty}^{\gamma + i\infty} e^{st} F(s) dt,
-        $$
-        where $\gamma$ is chosen so that the contour path of
-        integration is in the region of convergence of $F(s)$.
-
-        EXAMPLES:
-            sage: f = (1/(w^2+10)).inverse_laplace(w, m); f
-            sin(sqrt(10)*m)/sqrt(10)
-            sage: laplace(f, m, w)
-            1/(w^2 + 10)        
-        """
-        return self.parent()(self._maxima_().ilt(var(t), var(s)))
-    
-
-    ###################################################################
-    # a default variable, for convenience.
-    ###################################################################
-    def default_variable(self):
-        vars = self.variables()
-        if len(vars) < 1:
-            return var('x')
-        else:
-            return vars[0]
-
-    ###################################################################
-    # integration
-    ###################################################################
-    def integral(self, v=None, a=None, b=None):
-        """
-        Returns the indefinite integral with respect to the variable
-        $v$, ignoring the constant of integration. Or, if endpoints
-        $a$ and $b$ are specified, returns the definite integral over
-        the interval $[a, b]$.
-
-        If \code{self} has only one variable, then it returns the
-        integral with respect to that variable.
-
-        INPUT:
-            v -- (optional) a variable or variable name
-            a -- (optional) lower endpoint of definite integral
-            b -- (optional) upper endpoint of definite integral
-            
-        
-        EXAMPLES:
-            sage: h = sin(x)/(cos(x))^2
+            sage: h = sin(x)/cos(x)
             sage: h.integral(x)
-            1/cos(x)
-
-            sage: f = x^2/(x+1)^3
-            sage: f.integral()
-            log(x + 1) + (4*x + 3)/(2*x^2 + 4*x + 2)
-
-            sage: f = x*cos(x^2)
-            sage: f.integral(x, 0, sqrt(pi))
-            0
-            sage: f.integral(a=-pi, b=pi)
-            0
-
-        Constraints are sometimes needed:
-            sage: integral(x^n,x)
-            Traceback (most recent call last):
-            ...
-            TypeError: Computation failed since Maxima requested additional constraints (use assume):
-            Is  n+1  zero or nonzero?
-            sage: assume(n > 0)
-            sage: integral(x^n,x)
-            x^(n + 1)/(n + 1)
-            sage: forget()
-
-        NOTE: Above, putting assume(n == -1) does not yield the right behavior.
-        Directly in maxima, doing
-
-        The examples in the Maxima documentation:
-            sage: integral(sin(x)^3)
-            cos(x)^3/3 - cos(x)
-            sage: integral(x/sqrt(b^2-x^2))
-            x*log(2*sqrt(b^2 - x^2) + 2*b)
-            sage: integral(x/sqrt(b^2-x^2), x)
-            -sqrt(b^2 - x^2)
-            sage: integral(cos(x)^2 * exp(x), x, 0, pi)
-            3*e^pi/5 - 3/5
-            sage: integral(x^2 * exp(-x^2), x, -oo, oo)
-            sqrt(pi)/2
-
-        We integrate the same function in both Mathematica and SAGE (via Maxima):
-            sage: f = sin(x^2) + y^z
-            sage: g = mathematica(f)                           # optional  -- requires mathematica
-            sage: print g                                      # optional
-                      z        2
-                     y  + Sin[x ]
-            sage: print g.Integrate(x)                         # optional
-                        z        Pi                2
-                     x y  + Sqrt[--] FresnelS[Sqrt[--] x]
-                                 2                 Pi
-            sage: print f.integral(x)
-                  z                                         (sqrt(2)  I + sqrt(2)) x
-               x y  + sqrt( pi) ((sqrt(2)  I + sqrt(2)) erf(------------------------)
-                                                                       2
-                                                           (sqrt(2)  I - sqrt(2)) x
-                              + (sqrt(2)  I - sqrt(2)) erf(------------------------))/8
-                                                                      2
-                                                                          
-        We integrate the above function in maple now:
-            sage: g = maple(f); g                             # optional -- requires maple
-            sin(x^2)+y^z
-            sage: g.integrate(x)                              # optional -- requires maple
-            1/2*2^(1/2)*Pi^(1/2)*FresnelS(2^(1/2)/Pi^(1/2)*x)+y^z*x
-
-        We next integrate a function with no closed form integral.  Notice that
-        the answer comes back as an expression that contains an integral itself.
-            sage: A = integral(1/ ((x-4) * (x^3+2*x+1)), x); A
-            log(x - 4)/73 - (integrate((x^2 + 4*x + 18)/(x^3 + 2*x + 1), x)/73)
-            sage: print A
-                                     /  2
-                                     [ x  + 4 x + 18
-                                     I ------------- dx
-                                     ]  3
-                        log(x - 4)   / x  + 2 x + 1
-                        ---------- - ------------------
-                            73               73            
-        """
-
-        if v is None:
-            v = self.default_variable()
-            
+        """
         if not isinstance(v, SymbolicVariable):
-            v = var(repr(v))
-            #raise TypeError, 'must integrate with respect to a variable'
-        if (a is None and (not b is None)) or (b is None and (not a is None)):
-            raise TypeError, 'only one endpoint given'
-        if a is None:
-            return self.parent()(self._maxima_().integrate(v))
-        else:
-            return self.parent()(self._maxima_().integrate(v, a, b))
-
-    integrate = integral
-        
-    def nintegral(self, x, a, b,
-                  desired_relative_error='1e-8',
-                  maximum_num_subintervals=200):
-        r"""
-        Return a numerical approximation to the integral of self from
-        a to b.
-
-        INPUT:
-            x -- variable to integrate with respect to
-            a -- lower endpoint of integration
-            b -- upper endpoint of integration
-            desired_relative_error -- (default: '1e-8') the desired
-                 relative error
-            maximum_num_subintervals -- (default: 200) maxima number
-                 of subintervals
-
-        OUTPUT:
-            -- float: approximation to the integral
-            -- float: estimated absolute error of the approximation
-            -- the number of integrand evaluations
-            -- an error code:
-                  0 -- no problems were encountered
-                  1 -- too many subintervals were done
-                  2 -- excessive roundoff error
-                  3 -- extremely bad integrand behavior
-                  4 -- failed to converge
-                  5 -- integral is probably divergent or slowly convergent
-                  6 -- the input is invalid
-
-        ALIAS:
-            nintegrate is the same as nintegral
-
-        REMARK:
-            There is also a function \code{numerical_integral} that implements
-            numerical integration using the GSL C library.  It is potentially
-            much faster and applies to arbitrary user defined functions. 
-
-        EXAMPLES:
-            sage: exp(-sqrt(x)).nintegral(x, 0, 1)
-            (0.52848223531423055, 4.1633141378838452e-11, 231, 0)
-
-        We can also use the \code{numerical_integral} function, which calls
-        the GSL C library.
-            sage: numerical_integral(exp(-sqrt(x)), 0, 1)
-            (0.52848223225314706, 6.8392846084921134e-07)
-        """
-        v = self._maxima_().quad_qags(var(x),
-                                      a, b, desired_relative_error,
-                                      maximum_num_subintervals)
-        return float(v[0]), float(v[1]), Integer(v[2]), Integer(v[3])
-
-    nintegrate = nintegral
-
-    
-    ###################################################################
-    # Manipulating epxressions
-    ###################################################################
-    def coeff(self, x, n=1):
-        """
-        Returns the coefficient of $x^n$ in self.
-
-        INPUT:
-            x -- variable, function, expression, etc.
-            n -- integer, default 1.
-
-        Sometimes it may be necessary to expand or factor first, since
-        this is not done automatically.
-
-        EXAMPLES:
-            sage: f = (a*sqrt(2))*x^2 + sin(y)*x^(1/2) + z^z   
-            sage: f.coeff(sin(y))
-            sqrt(x)        
-            sage: f.coeff(x^2)
-            sqrt(2)*a
-            sage: f.coeff(x^(1/2))
-            sin(y)
-            sage: f.coeff(1)
-            0
-            sage: f.coeff(x, 0)
-            z^z
-        """
-        return self.parent()(self._maxima_().coeff(x, n))
-
-    def coeffs(self, x=None):
-        """
-        Coefficients of self as a polynomial in x.
-
-        INPUT:
-            x -- optional variable
-        OUTPUT:
-            list of pairs [expr, n], where expr is a symbolic expression and n is a power.
-
-        EXAMPLES:
-            sage: p = x^3 - (x-3)*(x^2+x) + 1
-            sage: p.coeffs()
-            [[1, 0], [3, 1], [2, 2]]
-            sage: p = expand((x-a*sqrt(2))^2 + x + 1); p
-            x^2 - 2*sqrt(2)*a*x + x + 2*a^2 + 1
-            sage: p.coeffs(a)
-            [[x^2 + x + 1, 0], [-2*sqrt(2)*x, 1], [2, 2]]
-            sage: p.coeffs(x)
-            [[2*a^2 + 1, 0], [1 - 2*sqrt(2)*a, 1], [1, 2]]
-
-        A polynomial with wacky exponents:
-            sage: p = (17/3*a)*x^(3/2) + x*y + 1/x + x^x
-            sage: p.coeffs(x)
-            [[1, -1], [x^x, 0], [y, 1], [17*a/3, 3/2]]        
-        """
-        f = self._maxima_()
-        P = f.parent()
-        P._eval_line('load(coeflist)')
-        if x is None:
-            x = self.default_variable()
-        x = var(x)
-        G = f.coeffs(x)
-        S = symbolic_expression_from_maxima_string(repr(G))
-        return S[1:]
-
-    def poly(self, x=None):
-        r"""
-        Express self as a polynomial in x.  Is self is not a polynomial
-        in x, then some coefficients may be functions of x.
-
-        WARNING: This is different from \code{self.polynomial()} which
-        returns a SAGE polynomial over a given base ring.
-
-        EXAMPLES:
-            sage: p = expand((x-a*sqrt(2))^2 + x + 1); p
-            x^2 - 2*sqrt(2)*a*x + x + 2*a^2 + 1
-            sage: p.poly(a)
-            (x^2 + x + 1)*1 + -2*sqrt(2)*x*a + 2*a^2
-            sage: bool(expand(p.poly(a)) == p)
-            True            
-            sage: p.poly(x)
-            (2*a^2 + 1)*1 + (1 - 2*sqrt(2)*a)*x + 1*x^2        
-        """
-        f = self._maxima_()
-        P = f.parent()
-        P._eval_line('load(coeflist)')
-        if x is None:
-            x = self.default_variable()
-        x = var(x)
-        G = f.coeffs(x)
-        ans = None
-        for i in range(1, len(G)):
-            Z = G[i]
-            coeff = SR(Z[0])
-            n = SR(Z[1])
-            if repr(coeff) != '0':
-                if repr(n) == '0':
-                    xpow = SR(1)
-                elif repr(n) == '1':
-                    xpow = x
-                else:
-                    xpow = x**n
-                if ans is None:
-                    ans = coeff*xpow
-                else:
-                    ans += coeff*xpow
-        ans._declare_simplified()
-        return ans
-
-    def combine(self):
-        """
-        Simplifies self by combining all terms with the same
-        denominator into a single term.
-
-        EXAMPLES:
-            sage: f = x*(x-1)/(x^2 - 7) + y^2/(x^2-7) + 1/(x+1) + b/a + c/a
-            sage: print f
-                                     2
-                                    y      (x - 1) x     1     c   b
-                                  ------ + --------- + ----- + - + -
-                                   2         2         x + 1   a   a
-                                  x  - 7    x  - 7
-            sage: print f.combine()
-                                     2
-                                    y  + (x - 1) x     1     c + b
-                                    -------------- + ----- + -----
-                                         2           x + 1     a
-                                        x  - 7        
-        """
-        return self.parent()(self._maxima_().combine())
-    
-    def numerator(self):
-        """
-        EXAMPLES:
-            sage: f = x*(x-a)/((x^2 - y)*(x-a))
-            sage: print f
-                                                  x
-                                                ------
-                                                 2
-                                                x  - y
-            sage: f.numerator()
-            x
-            sage: f.denominator()
-            x^2 - y
-        """
-        return self.parent()(self._maxima_().num())
-
-    def denominator(self):
-        """
-        EXAMPLES:
-            sage: f = (sqrt(x) + sqrt(y) + sqrt(z))/(x^10 - y^10 - sqrt(var('theta')))
-            sage: print f
-                                      sqrt(z) + sqrt(y) + sqrt(x)
-                                      ---------------------------
-                                          10    10
-                                       - y   + x   - sqrt(theta)
-            sage: f.denominator()
-            -y^10 + x^10 - sqrt(theta)
-        """
-        return self.parent()(self._maxima_().denom())
-    
-    ###################################################################
-    # solve
-    ###################################################################
-    def roots(self, x=None):
-        r"""
-        Returns the roots of self, with multiplicities.
-
-        INPUT:
-            x -- variable to view the function in terms of
-                   (use default variable if not given)
-        OUTPUT:
-            list of pairs (root, multiplicity)
-
-        If there are infinitely many roots, e.g., a function
-        like sin(x), only one is returned. 
-        
-        EXAMPLES:
-        A simple example:
-            sage: ((x^2-1)^2).roots()
-            [(-1, 2), (1, 2)]
-
-        A complicated example.
-            sage: f = expand((x^2 - 1)^3*(x^2 + 1)*(x-a)); f
-            x^9 - a*x^8 - 2*x^7 + 2*a*x^6 + 2*x^3 - 2*a*x^2 - x + a
-
-        The default variable is a, since it is the first in alphabetical order:
-            sage: f.roots()
-            [(x, 1)]
-
-        As a polynomial in a, x is indeed a root:
-            sage: f.poly(a)
-            (x^9 - 2*x^7 + 2*x^3 - x)*1 + (-x^8 + 2*x^6 - 2*x^2 + 1)*a
-            sage: f(a=x)
-            0
-
-        The roots in terms of x are what we expect:
-            sage: f.roots(x)
-            [(a, 1), (-1*I, 1), (I, 1), (1, 3), (-1, 3)]
-
-        Only one root of $\sin(x) = 0$ is given:
-            sage: f = sin(x)    
-            sage: f.roots(x)
-            [(0, 1)]
-
-        We derive the roots of a general quadratic polynomial:
-            sage: (a*x^2 + b*x + c).roots(x)
-            [((-sqrt(b^2 - 4*a*c) - b)/(2*a), 1), ((sqrt(b^2 - 4*a*c) - b)/(2*a), 1)]        
-        """
-        if x is None:
-            x = self.default_variable()
-        S, mul = self.solve(x, multiplicities=True)
-        return [(S[i].rhs(), mul[i]) for i in range(len(mul))]
-
-    def solve(self, x, multiplicities=False):
-        r"""
-        Solve the equation \code{self == 0} for the variable x.
-
-        INPUT:
-            x -- variable to solve for
-            multiplicities -- bool (default: False); if True, return corresponding multiplicities. 
-
-        EXAMPLES:
-            sage: (z^5 - 1).solve(z)
-            [z == e^(2*I*pi/5), z == e^(4*I*pi/5), z == e^(-(4*I*pi/5)), z == e^(-(2*I*pi/5)), z == 1]        
-        """
-        x = var(x)
-        return (self == 0).solve(x, multiplicities=multiplicities)
+            raise TypeError, "second argument to diff must be a variable"
+        return self.parent()(self._maxima_().integrate(v))
+        
 
     ###################################################################
@@ -1591,20 +273,13 @@
     ###################################################################
     def simplify(self):
-        try:
-            return self._simp
-        except AttributeError:
-            S = evaled_symbolic_expression_from_maxima_string(self._maxima_init_())
-            S._simp = S
-            self._simp = S
-            return S
+        return self.parent()(self._maxima_())
 
     def simplify_trig(self):
         r"""
-        First expands using trig_expand, then employs the identities
-        $\sin(x)^2 + \cos(x)^2 = 1$ and $\cosh(x)^2 - \sin(x)^2 = 1$
-        to simplify expressions containing tan, sec, etc., to sin,
-        cos, sinh, cosh.
-
-        ALIAS: trig_simplify and simplify_trig are the same
+        Employs the identities $\sin(x)^2 + \cos(x)^2 = 1$ and
+        $\cosh(x)^2 - \sin(x)^2 = 1$ to simplify expressions
+        containing tan, sec, etc., to sin, cos, sinh, cosh.
+
+        trig_simplify() and simplify_trig() are the same method.
         
         EXAMPLES:
@@ -1615,78 +290,9 @@
             sage: f.simplify_trig()
             1
-        """
-        # much better to expand first, since it often doesn't work
-        # right otherwise!
-        return self.parent()(self._maxima_().trigexpand().trigsimp())
+            
+        """
+        return self.parent()(self._maxima_().trigsimp())
 
     trig_simplify = simplify_trig
-
-    def simplify_rational(self):
-        """
-        Simplify by expanding repeatedly rational expressions.
-        
-        ALIAS: rational_simplify and simplify_rational are the same
-
-        EXAMPLES:
-            sage: f = sin(x/(x^2 + x))
-            sage: f
-            sin(x/(x^2 + x))
-            sage: f.simplify_rational()
-            sin(1/(x + 1))
-
-            sage: f = ((x - 1)^(3/2) - (x + 1)*sqrt(x - 1))/sqrt((x - 1)*(x + 1))
-            sage: print f
-                                          3/2
-                                   (x - 1)    - sqrt(x - 1) (x + 1)
-                                   --------------------------------
-                                        sqrt((x - 1) (x + 1))
-            sage: print f.simplify_rational()
-                                              2 sqrt(x - 1)
-                                            - -------------
-                                                    2
-                                              sqrt(x  - 1)            
-        """
-        return self.parent()(self._maxima_().fullratsimp())
-
-    rational_simplify = simplify_rational
-        
-    ###################################################################
-    # factor
-    ###################################################################
-    def factor(self, dontfactor=[]):
-        """
-        Factors self, containing any number of variables or functions,
-        into factors irreducible over the integers.
-
-        INPUT:
-            self -- a symbolic expression
-            dontfactor -- list (default: []), a list of variables with
-                          respect to which factoring is not to occur.
-                          Factoring also will not take place with
-                          respect to any variables which are less
-                          important (using the variable ordering
-                          assumed for CRE form) than those on the
-                          `dontfactor' list.
-
-        EXAMPLES:
-            sage: (x^3-y^3).factor()
-            (-(y - x))*(y^2 + x*y + x^2)
-            sage: factor(-8*y - 4*x + z^2*(2*y + x))
-            (2*y + x)*(z - 2)*(z + 2)
-            sage: f = -1 - 2*x - x^2 + y^2 + 2*x*y^2 + x^2*y^2
-            sage: F = factor(f/(36*(1 + 2*y + y^2)), dontfactor=[x])
-            sage: print F
-                                          2
-                                        (x  + 2 x + 1) (y - 1)
-                                        ----------------------
-                                              36 (y + 1)
-        """
-        if len(dontfactor) > 0:
-            m = self._maxima_()
-            name = m.name()
-            cmd = 'block([dontfactor:%s],factor(%s))'%(dontfactor, name)
-            return evaled_symbolic_expression_from_maxima_string(cmd)
-        else:
-            return self.parent()(self._maxima_().factor())
         
     ###################################################################
@@ -1707,5 +313,5 @@
             cos(2*x)*cos(y) - sin(2*x)*sin(y)
 
-        ALIAS: trig_expand and expand_trig are the same
+        ALIAS: trig_expand
         """
         return self.parent()(self._maxima_().trigexpand())
@@ -1714,217 +320,144 @@
 
 
+       
     ###################################################################
     # substitute
     ###################################################################
-    def substitute(self, in_dict=None, **kwds):
+    def substitute(self, dict=None, **kwds):
         """
         Takes the symbolic variables given as dict keys or as keywords and
         replaces them with the symbolic expressions given as dict values or as
-        keyword values.  Also run when you call a SymbolicExpression.
-
-        INPUT:
-            in_dict -- (optional) dictionary of inputs
-            **kwds  -- named parameters
-
+        keyword values. Also run when you call a SymbolicExpression.
+        
         EXAMPLES:
             sage: u = (x^3 - 3*y + 4*t)
             sage: u.substitute(x=y, y=t)
-            y^3 + t
+            y^3 - 3*t + 4*t
 
             sage: f = sin(x)^2 + 32*x^(y/2)
-            sage: f(x=2, y = 10)
-            sin(2)^2 + 1024
+            sage: f.substitute(x=2, y = 10)
+            sin(2)^2 + 32*2^(10/2)
 
             sage: f(x=pi, y=t)
-            32*pi^(t/2)
-
-            sage: f = 2*x^2 - sin(x)
-            sage: f(pi)
-            2*pi^2
+            sin(pi)^2 + 32*pi^(t/2)
+
+            sage: f(x=pi, y=t).simplify()
+            
 
         AUTHORS:
             -- Bobby Moretti: Initial version
         """
-        X = self.simplify()
-        kwds = self.__parse_in_dict(in_dict, kwds)
-        kwds = self.__varify_kwds(kwds)
-        return X._recursive_sub(kwds)
-
-    def subs(self, *args, **kwds):
-        return self.substitute(*args, **kwds)
+        if dict is not None:
+            for k, v in dict.iteritems():
+               kwds[str(k)] = v 
+        # find the keys from the keywords
+        return self._recursive_sub(kwds) 
 
     def _recursive_sub(self, kwds):
-        raise NotImplementedError, "implement _recursive_sub for type '%s'!"%(type(self))
-
-    def _recursive_sub_over_ring(self, kwds, ring):
-        raise NotImplementedError, "implement _recursive_sub_over_ring for type '%s'!"%(type(self))
-    
-    def __parse_in_dict(self, in_dict, kwds):
-        if in_dict is None:
-            return kwds
-        
-        if not isinstance(in_dict, dict):
-            if len(kwds) > 0:
-                raise ValueError, "you must not both give the variable and specify it explicitly when doing a substitution."
-            in_dict = SR(in_dict)
-            vars = self.variables()
-            #if len(vars) > 1:
-            #    raise ValueError, "you must specify the variable when doing a substitution, e.g., f(x=5)"
-            if len(vars) == 0:
-                return {}
+        # if we have operands, call ourself on each operand
+        try:
+            ops = self._operands
+        except AttributeError:
+            pass
+        if isinstance(self, SymbolicVariable):
+            s = str(self)
+            if s in kwds:
+                return kwds[s]
             else:
-                return {vars[0]: in_dict}
-
-        # merge dictionaries
-        kwds.update(in_dict)
-        return kwds
-
-    def __varify_kwds(self, kwds):
-        return dict([(var(k),w) for k,w in kwds.iteritems()])
-        
-    def substitute_over_ring(self, in_dict=None, ring=None, **kwds):
-        X = self.simplify()
-        kwds = self.__parse_in_dict(in_dict, kwds)
-        kwds = self.__varify_kwds(kwds)
-        if ring is None:
-            return X._recursive_sub(kwds)
+                return self
+        elif isinstance(self, SymbolicConstant):
+            return self
+        elif isinstance(self, SymbolicArithmetic):
+            new_ops = [op._recursive_sub(kwds) for op in ops]
+            return SymbolicArithmetic([new_ops[0], new_ops[1]], self._operator) 
+        elif isinstance(self, SymbolicComposition):
+            return SymbolicComposition(ops[0], ops[1]._recursive_sub(kwds))
+
+class PrimitiveFunction(SymbolicExpression):
+    def __init__(self):
+        pass
+
+    def __call__(self, x):
+        # if we're calling with a symbolic expression, do function composition
+        if isinstance(x, SymbolicExpression) and not isinstance(x, Constant):
+            return SymbolicComposition(self, x)
+
+        # if x is a polynomial object, first turn it into a function and
+        # compose self with x
+        elif is_Polynomial(x):
+            return Function_composition(self, SymbolicPolynomial(x))
+
+        # if we can't figure out what x is, return a symbolic version of x
+        elif isinstance(x, (Integer, Rational,
+                            int, long, float, complex)):
+            return self(Constant_object(x))
+
         else:
-            return X._recursive_sub_over_ring(kwds, ring)
-
-        
-    ###################################################################
-    # Real and imaginary parts
-    ###################################################################
-    def real(self):
-        """
-        Return the real part of self.
-
-        EXAMPLES:
-            sage: a = log(3+4*I)
-            sage: print a
-                                             log(4  I + 3)
-            sage: print a.real()
-                                                log(5)
-            sage: print a.imag()
-                                                     4
-                                                atan(-)
-                                                     3
-
-        Now make a and b symbolic and compute the general real part:
-            sage: restore('a,b')    
-            sage: f = log(a + b*I)
-            sage: f.real()
-            log(b^2 + a^2)/2
-        """
-        return self.parent()(self._maxima_().real())
-        
-    def imag(self):
-        """
-        Return the imaginary part of self.
-
-        EXAMPLES:
-            sage: sqrt(-2).imag()
-            sqrt(2)
-
-        We simplify Ln(Exp(z)) to z for -Pi<Im(z)<=Pi:
-
-            sage: f = log(exp(z))
-            sage: assume(-pi < imag(z))
-            sage: assume(imag(z) <= pi)
-            sage: print f
-        			       z
-            sage: forget()
-
-        A more symbolic example:
-            sage: f = log(a + b*I)
-            sage: f.imag()
-            atan(b/a)
-        """
-        return self.parent()(self._maxima_().imag())
-
-    def conjugate(self):
-        """
-        The complex conjugate of self.
-        
-        EXAMPLES:
-            sage: a = 1 + 2*I 
-            sage: a.conjugate()
-            1 - 2*I
-            sage: a = sqrt(2) + 3^(1/3)*I; a
-            3^(1/3)*I + sqrt(2)
-            sage: a.conjugate()
-            sqrt(2) - 3^(1/3)*I
-        """
-        return self.parent()(self._maxima_().conjugate())
-
-    def norm(self):
-        """
-        The complex norm of self, i.e., self times its complex conjugate.
-
-        EXAMPLES:
-            sage: a = 1 + 2*I 
-            sage: a.norm()
-            5
-            sage: a = sqrt(2) + 3^(1/3)*I; a
-            3^(1/3)*I + sqrt(2)
-            sage: a.norm()
-            3^(2/3) + 2
-            sage: CDF(a).norm()
-            4.08008382305
-            sage: CDF(a.norm())
-            4.08008382305            
-        """
-        m = self._maxima_()
-        return self.parent()((m*m.conjugate()).expand())
-
-    ###################################################################
-    # Partial fractions
-    ###################################################################
-    def partial_fraction(self, var=None):
-        """
-        Return the partial fraction expansion of self with respect to
-        the given variable.
-
-        INPUT:
-            var -- variable name or string (default: first variable)
-
-        OUTPUT:
-            Symbolic expression
-
-        EXAMPLES:
-            sage: f = x^2/(x+1)^3
-            sage: f.partial_fraction()
-            1/(x + 1) - (2/(x + 1)^2) + 1/(x + 1)^3
-            sage: print f.partial_fraction()
-                                        1        2          1
-                                      ----- - -------- + --------
-                                      x + 1          2          3
-                                              (x + 1)    (x + 1)
-
-        Notice that the first variable in the expression is used by default:
-            sage: f = y^2/(y+1)^3
-            sage: f.partial_fraction()
-            1/(y + 1) - (2/(y + 1)^2) + 1/(y + 1)^3
-
-            sage: f = y^2/(y+1)^3 + x/(x-1)^3
-            sage: f.partial_fraction()
-            y^2/(y^3 + 3*y^2 + 3*y + 1) + 1/(x - 1)^2 + 1/(x - 1)^3
-
-        You can explicitly specify which variable is used. 
-            sage: f.partial_fraction(y)
-            1/(y + 1) - (2/(y + 1)^2) + 1/(y + 1)^3 + x/(x^3 - 3*x^2 + 3*x - 1)
-        """
-        if var is None:
-            var = self._first_variable()
-        return self.parent()(self._maxima_().partfrac(var))
-
-
-
+            return self(Symbolic_object(x))
+ 
+
+class CallableFunction(SageObject):
+    r'''
+    A callable, symbolic function that knows the variables on which it depends.
+    '''
+    def __init__(self, expr, args):
+        if args == [] or args == () or args is None:
+            raise ValueError, "A CallableFunction must know at least one of \
+                                its variables."
+        for arg in args:
+            if not isinstance(arg, SymbolicExpression):
+                raise TypeError, "Must construct a function with a list of \
+                                  SymbolicVariables."
+
+            self._varlist = args
+            self._expr = expr
+        
+
+    def __call__(self, *args):
+        vars = self._varlist
+        dct = {}
+        for i in range(len(args)):
+            dct[vars[i]] = args[i]
+
+        return self._expr.substitute(dct)
+
+    def _repr_(self):
+        if len(self._varlist) == 1:
+            return "%s |--> %s" % (self._varlist[0], self._expr._repr_())
+        else:
+            vars = ", ".join(map(str, self._varlist))
+            return "(%s) |--> %s" % (vars, self._expr._repr_())
+
+    def _latex_(self):
+        if len(self._varlist) == 1:
+            return "%s \\ {\mapsto}\\ %s" % (self._varlist[0],
+                    self._expr._latex_())
+        else:
+            vars = ", ".join(map(latex, self._varlist))
+            # the weird TeX is to workaround an apparent JsMath bug
+            return "\left(%s \\right)\\ {\\mapsto}\\ %s" % (vars, self._expr._latex_())
+
+    def derivative(self, dt):
+        return CallableFunction(self._expr.derivative(dt), self._varlist)
+
+    def integral(self, dx):
+        return CallableFunction(self._expr.integral(dx), self._varlist)
+
+    def substitute(self, dict=None, **kwds):
+        return CallableFunction(self._expr.substitute(dict, kwds), self._varlist)
+
+    def simplify(self):
+        return CallableFunction(self._expr.simplify(), self._varlist)
+
+    def trig_simplify(self):
+        return CallableFunction(self._expr.trig_simplify(), self._varlist)
+
+    #TODO: Arithmetic, expand, trig_expand, etc...
 
 class Symbolic_object(SymbolicExpression):
-    r"""
-    A class representing a symbolic expression in terms of a SageObject (not
-    necessarily a 'constant').
-    """
+    r'''
+    A class representing a symbolic expression in terms of a SageObject.
+    '''
+
     def __init__(self, obj):
         SymbolicExpression.__init__(self)
@@ -1932,56 +465,51 @@
 
     def obj(self):
-        """
-        EXAMPLES:
-        """
         return self._obj
 
-    def __float__(self):
-        """
-        EXAMPLES:
-        """
-        return float(self._obj)
-
-    def __complex__(self):
-        """
-        EXAMPLES:
-        """
-        return complex(self._obj)
-
-    def _mpfr_(self, field):
-        """
-        EXAMPLES:
-        """
-        return field(self._obj)
-    
-    def _complex_mpfr_field_(self, C):
-        """
-        EXAMPLES:
-        """
-        return C(self._obj)
-
-    def _complex_double_(self, C):
-        """
-        EXAMPLES:
-        """
-        return C(self._obj)
-
-    def _real_double_(self, R):
-        """
-        EXAMPLES:
-        """
-        return R(self._obj)
-       
-    def _repr_(self, simplify=True):
-        """
-        EXAMPLES:
-        """
-        return repr(self._obj)
-
-    def _latex_(self):
-        """
-        EXAMPLES:
-        """
+    def _repr_(self):
+        return str(self._obj)
+
+    def _latex_(self):
         return latex(self._obj)
+
+    def __pow__(self, right):
+        if isinstance(right, Symbolic_object):
+            try:
+                return Symbolic_object(self._obj + right._obj)
+            except TypeError:
+                pass
+        return SymbolicExpression.__pow__(self, right)
+
+    def _add_(self, right):
+        if isinstance(right, Symbolic_object):
+            try:
+                return Symbolic_object(self._obj + right._obj)
+            except TypeError:
+                pass
+        return SymbolicExpression._add_(self, right)
+
+    def _sub_(self, right):
+        if isinstance(right, Symbolic_object):
+            try:
+                return Symbolic_object(self._obj - right._obj)
+            except TypeError:
+                pass
+        return SymbolicExpression._sub_(self, right)
+
+    def _mul_(self, right):
+        if isinstance(right, Symbolic_object):
+            try:
+                return Symbolic_object(self._obj * right._obj)
+            except TypeError:
+                pass
+        return SymbolicExpression._mul_(self, right)
+
+    def _div_(self, right):
+        if isinstance(right, Symbolic_object):
+            try:
+                return Symbolic_object(self._obj / right._obj)
+            except TypeError:
+                pass
+        return SymbolicExpression._div_(self, right)
 
     def str(self, bits=None):
@@ -1992,144 +520,28 @@
             return str(R(self._obj))
 
-    def _maxima_init_(self):
-        return maxima_init(self._obj)    
-
-    def _sys_init_(self, system):
-        return sys_init(self._obj, system)
-
-def maxima_init(x):
-    try:
-        return x._maxima_init_()
-    except AttributeError:
-        return repr(x)
-
-def sys_init(x, system):
-    try:
-        return x.__getattribute__('_%s_init_'%system)()
-    except AttributeError:
-        try:
-            return x._system_init_(system)
+    def _maxima_(self, maxima=maxima):
+        try:
+            return self.__maxima
         except AttributeError:
-            return repr(x)
-
-class SymbolicConstant(Symbolic_object):
-    def __init__(self, x):
-        Symbolic_object.__init__(self, x)
-
-    def _is_atomic(self):
-        try:
-            return self._atomic
-        except AttributeError:
-            if isinstance(self, Rational):
-                self._atomic = False
-            else:
-                self._atomic = True
-            return self._atomic
-
-    def _recursive_sub(self, kwds):
-        """
-        EXAMPLES:
-            sage: a = SR(5/6)
-            sage: type(a)
-            <class 'sage.calculus.calculus.SymbolicConstant'>
-            sage: a(x=3)
-            5/6
-        """
-        return self
-
-    def _recursive_sub_over_ring(self, kwds, ring):
-        return ring(self)
-    
-
+            m = maxima(self._obj)
+            self.__maxima = m
+            return m
 
 class SymbolicPolynomial(Symbolic_object):
-    """
-    An element of a polynomial ring as a formal symbolic expression.
-
-    EXAMPLES:
-    A single variate polynomial:
-        sage: R.<x> = QQ[]
-        sage: f = SR(x^3 + x)
-        sage: f(y=7)
-        x^3 + x
-        sage: f(x=5)
-        130
-        sage: f.integral(x)
-        x^4/4 + x^2/2
-        sage: f(x=y)
-        y^3 + y
-
-    A multivariate polynomial:
-    
-        sage: R.<x,y,theta> = ZZ[]
-        sage: f = SR(x^3 + x + y + theta^2); f
-        theta^2 + y + x + x^3
-        sage: f(x=y, theta=y)
-        y^3 + y^2 + 2*y
-        sage: f(x=5)
-        y + theta^2 + 130
-        
-    The polynomial must be over a field of characteristic 0.
-        sage: R.<w> = GF(7)[]
-        sage: f = SR(w^3 + 1)
-        Traceback (most recent call last):
-        ...
-        TypeError: polynomial must be over a field of characteristic 0.    
-    """
-    # for now we do nothing except pass the info on to the superconstructor. It's
+    "An element of a polynomial ring as a formal symbolic expression."
+
+    # for now we do nothing except pass the info on to the supercontructor. It's
     # not clear to me why we need anything else in this class -Bobby
     def __init__(self, p):
-        if p.parent().base_ring().characteristic() != 0:
-            raise TypeError, "polynomial must be over a field of characteristic 0."
-        Symbolic_object.__init__(self, p)
-
-    def _recursive_sub(self, kwds):
-        return self._recursive_sub_over_ring(kwds, ring)
-
-    def _recursive_sub_over_ring(self, kwds, ring):
-        f = self._obj
-        if is_Polynomial(f):
-            # Single variable case
-            v = f.parent().variable_name()
-            if kwds.has_key(v):
-                return ring(f(kwds[v]))
-            else:
-                if not ring is SR:
-                    return ring(self)
-        else:
-            # Multivariable case
-            t = []
-            for g in f.parent().gens():
-                s = repr(g)
-                if kwds.has_key(s):
-                    t.append(kwds[s])
-                else:
-                    t.append(g)
-            return ring(f(*t))
-
-    def polynomial(self, base_ring):
-        """
-        Return self as a polynomial over the given base ring, if possible.
-
-        INPUT:
-           base_ring -- a ring
-
-        EXAMPLES:
-            sage: R.<x> = QQ[]
-            sage: f = SR(x^2 -2/3*x + 1)
-            sage: f.polynomial(QQ)
-            x^2 - 2/3*x + 1
-            sage: f.polynomial(GF(19))
-            x^2 + 12*x + 1
-        """
-        f = self._obj
-        if base_ring is f.base_ring():
-            return f
-        return f.change_ring(base_ring)
-
-##################################################################
-        
-
-zero_constant = SymbolicConstant(Integer(0))
+       Symbolic_object.__init__(self, p) 
+
+class SymbolicConstant(SymbolicExpression):
+    def __call__(self, x):
+        return self
+
+class Constant_object(SymbolicConstant, Symbolic_object):
+    pass
+
+zero_constant = Constant_object(Integer(0))
 
 class SymbolicOperation(SymbolicExpression):
@@ -2139,42 +551,33 @@
     def __init__(self, operands):
         SymbolicExpression.__init__(self)
-        self._operands = operands   # don't even make a copy -- ok, since immutable.
-
-    def variables(self, vars=tuple([])):
-        """
-        Return sorted list of variables that occur in the simplified
-        form of self.  The ordering is alphabetic.
-
-        EXAMPLES:
-            sage: f = (x - x) + y^2 - z/z + (w^2-1)/(w+1); f
-            y^2 + (w^2 - 1)/(w + 1) - 1
-            sage: f.variables()
-            (w, y)
-
-            sage: (x + y + z + a + b + c).variables()
-            (a, b, c, x, y, z)
-
-            sage: (x^2 + x).variables()
-            (x,)
-        """
-        if not self.is_simplified():
-            return self.simplify().variables(vars)
-        
-        try:
-            return self.__variables
+        self._operands = [SER(op) for op in operands]
+
+class SymbolicComposition(SymbolicOperation):
+    r'''
+    Represents the symbolic composition of $f \circ g$.
+    '''
+    def __init__(self, f, g):
+        SymbolicOperation.__init__(self, [f,g])
+
+    def _is_atomic(self):
+        return True
+
+    def _repr_(self):
+        ops = self._operands
+        return "%s(%s)"% (ops[0]._repr_(), ops[1]._repr_())
+
+    def _latex_(self):
+        ops = self._operands
+        return r"%s \left( %s \right)"% (latex(ops[0]), latex(ops[1]))
+
+    def _maxima_(self, maxima=maxima):
+        try:
+            return self.__maxima
         except AttributeError:
-            pass
-        if vars is None:
-            vars = []
-        else:
-            vars = list(vars)
-        vars = list(set(sum([list(op.variables()) for op in self._operands], [])))
-        vars.sort(var_cmp)
-        vars = tuple(vars)
-        self.__variables = vars
-        return vars
-
-def var_cmp(x,y):
-    return cmp(str(x), str(y))
+            ops = self._operands
+            m = ops[0]._maxima_(maxima)(ops[1]._maxima_(maxima))
+            self.__maxima = m
+            return m
+        
 
 symbols = {operator.add:' + ', operator.sub:' - ', operator.mul:'*',
@@ -2183,176 +586,82 @@
 
 class SymbolicArithmetic(SymbolicOperation):
-    r"""
+    r'''
     Represents the result of an arithemtic operation on
     $f$ and $g$.
-    """
+    '''
+
     def __init__(self, operands, op):
         SymbolicOperation.__init__(self, operands)
+        
+        if op is operator.add:
+            self._atomic = False
+        elif op is operator.sub:
+            self._atomic = False
+        elif op is operator.mul:
+            self._atomic = True
+        elif op is operator.div:
+            self._atomic = False
+        elif op is operator.pow:
+            self._atomic = True
+        elif op is operator.neg:
+            self._atomic = False
+
         self._operator = op
 
-    def _recursive_sub(self, kwds):
-        """
-        EXAMPLES:
-            sage: f = (x - x) + y^2 - z/z + (w^2-1)/(w+1); f
-            y^2 + (w^2 - 1)/(w + 1) - 1
-            sage: f(y=10)
-            (w^2 - 1)/(w + 1) + 99
-            sage: f(w=1,y=10)
-            99
-            sage: f(y=w,w=y)
-            (y^2 - 1)/(y + 1) + w^2 - 1
-
-            sage: f = y^5 - sqrt(2)
-            sage: f(10)
-            100000 - sqrt(2)
-        """
-        ops = self._operands
-        new_ops = [SR(op._recursive_sub(kwds)) for op in ops]
-        return self._operator(*new_ops)
-
-    def _recursive_sub_over_ring(self, kwds, ring):
-        ops = self._operands
-        if self._operator == operator.pow:
-            new_ops = [ops[0]._recursive_sub_over_ring(kwds, ring=ring), Integer(ops[1])]
-        else:
-            new_ops = [op._recursive_sub_over_ring(kwds, ring=ring) for op in ops]                
-        return ring(self._operator(*new_ops))
-        
-    def __float__(self):
-        fops = [float(op) for op in self._operands]
-        return self._operator(*fops)
-
-    def __complex__(self):
-        fops = [complex(op) for op in self._operands]
-        return self._operator(*fops)
-
-    def _mpfr_(self, field):
-        if not self.is_simplified():
-            return self.simplify()._mpfr_(field)
-        rops = [op._mpfr_(field) for op in self._operands]
-        return self._operator(*rops)
-
-    def _complex_mpfr_field_(self, field):
-        if not self.is_simplified():
-            return self.simplify()._complex_mpfr_field_(field)
-        rops = [op._complex_mpfr_field_(field) for op in self._operands]
-        return self._operator(*rops)
-
-    def _complex_double_(self, field):
-        if not self.is_simplified():
-            return self.simplify()._complex_double_(field)
-        rops = [op._complex_double_(field) for op in self._operands]
-        return self._operator(*rops)
-
-    def _real_double_(self, field):
-        if not self.is_simplified():
-            return self.simplify()._real_double_(field)
-        rops = [op._real_double_(field) for op in self._operands]
-        return self._operator(*rops)
-
     def _is_atomic(self):
-        try:
-            return self._atomic
-        except AttributeError:
-            op = self._operator
-            # todo: optimize with a dictionary
-            if op is operator.add:
-                self._atomic = False
-            elif op is operator.sub:
-                self._atomic = False
-            elif op is operator.mul:
-                self._atomic = True
-            elif op is operator.div:
-                self._atomic = False
-            elif op is operator.pow:
-                self._atomic = True
-            elif op is operator.neg:
-                self._atomic = False
-            return self._atomic
-
-    def _repr_(self, simplify=True):
-        """
-        TESTS:
-            sage: a = (1-1/r)^(-1); a
-            1/(1 - (1/r))
-            sage: a.derivative(r)
-            -1/((1 - (1/r))^2*r^2)
-
-            sage: reset('a,b')
-            sage: s = 0*(1/a) + -b*(1/a)*(1 + -1*0*(1/a))*(1/(a*b + -1*b*(1/a)))
-            sage: s
-            -b/(a*(a*b - (b/a)))
-            sage: s(a=2,b=3)
-            -1/3
-            sage: -3/(2*(2*3-(3/2)))
-            -1/3
-        """
-        if simplify:
-            if hasattr(self, '_simp'):
-                return self._simp._repr_(simplify=False)
-            else:
-                return self.simplify()._repr_(simplify=False)
+        return self._atomic
+
+    def _repr_(self):
 
         ops = self._operands
         op = self._operator
-
-        ###############
-        # some bugs here in parenthesis -- exposed by above doctest
-        ###############
-        
-        s = [o._repr_(simplify=False) for o in ops]
-        
+        
+        s = [str(o) for o in ops]
         # for the left operand, we need to surround it in parens when the
         # operator is mul/div/pow, and when the left operand contains an
         # operation of lower precedence
-        if op in [operator.mul, operator.div]: 
+        if op in [operator.mul, operator.div, operator.pow]:
             if ops[0]._has_op(operator.add) or ops[0]._has_op(operator.sub):
                 if not ops[0]._is_atomic():
                     s[0] = '(%s)' % s[0]
-            else:
-                try:
-                    if isinstance(ops[0]._obj, Rational):
-                        s[0] = '(%s)' % s[0]
-                except AttributeError:
-                    pass
-                try:
-                    if isinstance(ops[1]._obj, Rational):
-                        s[1] = '(%s)' % s[1]
-                except AttributeError:
-                    pass
-
-        # for the right operand, we need to surround it in parens when
-        # the operation is mul/div/sub, and when the right operand
-        # contains a + or -.
-        if op in [operator.mul, operator.sub]:
+        # for the right operand, we need to surround it in parens when the
+        # operation is mul/div/sub and the, and when the right operand contains
+        # a + or -.
+        if op in [operator.mul, operator.div, operator.sub]:
+            if ops[1]._has_op(operator.add) or ops[1]._has_op(operator.sub):
                 # avoid drawing parens if s1 an atomic operation
                 if not ops[1]._is_atomic():
                     s[1] = '(%s)' % s[1]
-
-        elif op is operator.div:
-            if not ops[1]._is_atomic() or ops[1]._has_op(operator.mul):
+        # if we have a compound expression on the right, then we need parens on
+        # the right... but in TeX, this is expressed by font size and position
+        elif op is operator.pow:
+            if ops[1]._has_op(operator.add) or  \
+            ops[1]._has_op(operator.sub) or  \
+            ops[1]._has_op(operator.mul) or  \
+            ops[1]._has_op(operator.div) or  \
+            ops[1]._has_op(operator.pow):
                 s[1] = '(%s)' % s[1]
-
-        elif op is operator.pow:
-            if not ops[0]._is_atomic():
-                s[0] = '(%s)'% s[0]
-            if not ops[1]._is_atomic() or ('/' in s[1] or '*' in s[1]):
-                s[1] = '(%s)'% s[1]
-
         if op is operator.neg:
-            if ops[0]._is_atomic():
-                return '-%s' % s[0]
-            else:
-                return '-(%s)'%s[0]
+            return '-%s' % s[0]
         else:
             return '%s%s%s' % (s[0], symbols[op], s[1])
 
     def _latex_(self):
-        # if we are not simplified, return the latex of a simplified version
-        if not self.is_simplified():
-            return self.simplify()._latex_()
         op = self._operator
         ops = self._operands
-        s = [x._latex_() for x in self._operands]
+        ops_tex = [x._latex_() for x in self._operands]
+
+        s = [o._latex_() for o in ops]
+        
+        # follow a very similar logic to _repr_, but we don't parenthesize
+        # exponents
+        if op in [operator.mul, operator.div, operator.pow]:
+            if ops[0]._has_op(operator.add) or ops[0]._has_op(operator.sub):
+                if not ops[0]._is_atomic():
+                    s[0] = '\\left( %s \\right)' % s[0]
+        if op in [operator.mul, operator.div, operator.sub]:
+            if ops[1]._has_op(operator.add) or ops[1]._has_op(operator.sub):
+                if not ops[1]._is_atomic():
+                    s[1] = '\\left( %s \\right)' % s[1]
 
         if op is operator.add:
@@ -2361,35 +670,24 @@
             return '%s - %s' % (s[0], s[1])
         elif op is operator.mul:
-            if ops[0]._has_op(operator.add) or ops[0]._has_op(operator.sub):
-                s[0] = r'\left( %s \right)' %s[0]
             return '{%s \\cdot %s}' % (s[0], s[1])
         elif op is operator.div:
             return '\\frac{%s}{%s}' % (s[0], s[1])
         elif op is operator.pow:
-            if ops[0]._has_op(operator.add) or ops[0]._has_op(operator.sub) \
-               or ops[0]._has_op(operator.mul) or ops[0]._has_op(operator.div) \
-               or ops[0]._has_op(operator.pow):
-                s[0] = r'\left( %s \right)' % s[0]
             return '{%s}^{%s} ' % (s[0], s[1])
         elif op is operator.neg:
             return '-%s' % s[0]
 
-    def _maxima_init_(self):
-        ops = self._operands
-        if self._operator is operator.neg:
-            return '-(%s)' % ops[0]._maxima_init_()
-        else:
-            return '(%s) %s (%s)' % (ops[0]._maxima_init_(),
-                             infixops[self._operator],
-                             ops[1]._maxima_init_())
-
-    def _sys_init_(self, system):
-        ops = self._operands
-        if self._operator is operator.neg:
-            return '-(%s)' % sys_init(ops[0], system)
-        else:
-            return '(%s) %s (%s)' % (sys_init(ops[0], system),
-                             infixops[self._operator],
-                             sys_init(ops[1], system))
+    def _maxima_(self, maxima=maxima):
+        try:
+            return self.__maxima
+        except AttributeError:
+            ops = self._operands
+            if self._operator is operator.neg:
+                m = self._operator(ops[0]._maxima_(maxima))
+            else:
+                m = self._operator(ops[0]._maxima_(maxima),
+                                      ops[1]._maxima_(maxima))
+            self.__maxima = m
+            return m
 
 import re
@@ -2402,34 +700,8 @@
             raise ValueError, "variable name must be nonempty"
 
-    def _recursive_sub(self, kwds):
-        # do the replacement if needed
-        if kwds.has_key(self):
-            return kwds[self]
-        else:
-            return self
-
-    def _recursive_sub_over_ring(self, kwds, ring):
-        if kwds.has_key(self):
-            return ring(kwds[self])
-        else:
-            return ring(self)
-
-    def variables(self, vars=tuple([])):
-        """
-        Return sorted list of variables that occur in the simplified
-        form of self.
-        """
-        return (self, )
-
-    def __cmp__(self, right):
-        if isinstance(right, SymbolicVariable):
-            return cmp(self._repr_(), right._repr_())
-        else:
-            return SymbolicExpression.__cmp__(self, right)
-
-    def _repr_(self, simplify=True):
-        return self._name
-
-    def __str__(self):
+    def __call__(self, x):
+        raise AttributeError, "A symbolic variable is not callable."
+
+    def _repr_(self):
         return self._name
 
@@ -2451,9 +723,11 @@
         return a
 
-    def _maxima_init_(self):
-        return self._name
-
-    def _sys_init_(self, system):
-        return self._name
+    def _maxima_(self, maxima=maxima):
+        try:
+            return self.__maxima
+        except AttributeError:
+            m = maxima(self._name)
+            self.__maxima = m
+            return m
 
 common_varnames = ['alpha',
@@ -2498,1614 +772,105 @@
     
 _vars = {}
-def var(s, create=True):
-    r"""
-    Create a symbolic variable with the name \emph{s}.
-
-    EXAMPLES:
-        sage: var('xx')
-        xx
-    """
-    if isinstance(s, SymbolicVariable):
-        return s
-    s = str(s)
-    if ',' in s:
-        return tuple([var(x.strip()) for x in s.split(',')])
-    elif ' ' in s:
-        return tuple([var(x.strip()) for x in s.split()])
+def var(s):
+    r''' Create a symbolic variable with the name \emph{s}'''
     try:
-        X = _vars[s]()
-        if not X is None:
-            return X
+        return _vars[s]
     except KeyError:
-        if not create:
-            raise ValueError, "the variable '%s' has not been defined"%var
-        pass
-    v = SymbolicVariable(s)
-    _vars[s] = weakref.ref(v)
-    _syms[s] = v
-    return v
-
-
-#########################################################################################
-#  Callable functions
-#########################################################################################
-def is_CallableSymbolicExpressionRing(x):
-    """
-    EXAMPLES:
-        sage: is_CallableSymbolicExpressionRing(QQ)
-        False
-        sage: is_CallableSymbolicExpressionRing(CallableSymbolicExpressionRing((x,y,z)))
-        True
-    """
-    return isinstance(x, CallableSymbolicExpressionRing_class)
-
-class CallableSymbolicExpressionRing_class(CommutativeRing):
-    def __init__(self, args):
-        self._default_precision = 53 # default precision bits
-        self._args = args
-        ParentWithBase.__init__(self, RR)
-
-    def __call__(self, x):
-        """
-
-        TESTS:
-            sage: f(x) = x+1; g(y) = y+1
-            sage: f.parent()(g)
-            x |--> y + 1
-            sage: g.parent()(f)
-            y |--> x + 1
-            sage: f(x) = x+2*y; g(y) = y+3*x
-            sage: f.parent()(g)
-            x |--> y + 3*x
-            sage: g.parent()(f)
-            y |--> 2*y + x
-        """
-        return self._coerce_impl(x)
-
-    def _coerce_impl(self, x):
-        if isinstance(x, SymbolicExpression):
-            if isinstance(x, CallableSymbolicExpression):
-                x = x._expr
-            return CallableSymbolicExpression(self, x)
-        return self._coerce_try(x, [SR])
-
-    def _repr_(self):
-        return "Callable function ring with arguments %s"%(self._args,)
-
-    def args(self):
-        return self._args
-
-    def arguments(self):
-        return self.args()
-
-    def zero_element(self):
-        try:
-            return self.__zero_element
-        except AttributeError:
-            z = CallableSymbolicExpression(SR.zero_element(), self._args)
-            self.__zero_element = z
-            return z
-
-    def _an_element_impl(self):
-        return self.zero_element()
-
-
-_cfr_cache = {}
-def CallableSymbolicExpressionRing(args, check=True):
-    if check:
-        if len(args) == 1 and isinstance(args[0], (list, tuple)):
-            args = args[0]
-        for arg in args:
-            if not isinstance(arg, SymbolicVariable):
-                raise TypeError, "Must construct a function with a tuple (or list) of" \
-                                +" SymbolicVariables."
-        args = tuple(args)
-    if _cfr_cache.has_key(args):
-        R = _cfr_cache[args]()
-        if not R is None:
-            return R
-    R = CallableSymbolicExpressionRing_class(args)
-    _cfr_cache[args] = weakref.ref(R)
-    return R
-
-def is_CallableSymbolicExpression(x):
-    """
-    Returns true if x is a callable symbolic expression.
-    
-    EXAMPLES:
-        sage: f(x,y) = a + 2*x + 3*y + z
-        sage: is_CallableSymbolicExpression(f)
-        True
-        sage: is_CallableSymbolicExpression(a+2*x)
-        False
-        sage: def foo(n): return n^2
-        ...
-        sage: is_CallableSymbolicExpression(foo)
-        False
-    """
-    return isinstance(x, CallableSymbolicExpression)
-
-class CallableSymbolicExpression(SymbolicExpression):
-    r"""
-    A callable symbolic expression that knows the ordered list of
-    variables on which it depends.
-
-    EXAMPLES:
-        sage: f(x,y) = a + 2*x + 3*y + z
-        sage: f
-        (x, y) |--> z + 3*y + 2*x + a
-        sage: f(1,2)
-        z + a + 8
-    """
-    def __init__(self, parent, expr):
-        RingElement.__init__(self, parent)
-        self._expr = expr
-
-    def variables(self):
-        """
-        EXAMPLES:
-            sage: g(x) = sin(x) + a
-            sage: g.variables()
-            (a, x)
-            sage: g.args()
-            (x,)
-            sage: g(y,x,z) = sin(x) + a - a
-            sage: g
-            (y, x, z) |--> sin(x)
-            sage: g.args()
-            (y, x, z)
-        """
-        return self._expr.variables()
-
-    def expression(self):
-        """
-        Return the underlying symbolic expression (i.e., forget the
-        extra map structure).
-        """
-        return self._expr
-
-    def args(self):
-        return self.parent().args()
-
-    def _maxima_init_(self):
-        return self._expr._maxima_init_()
-
-    def __float__(self):
-        return float(self._expr)
-
-    def __complex__(self):
-        return complex(self._expr)
-    
-    def _mpfr_(self, field):
-        """
-        Coerce to a multiprecision real number.
-
-        EXAMPLES:
-            sage: RealField(100)(SR(10))
-            10.000000000000000000000000000
-        """
-        return (self._expr)._mpfr_(field)
-
-    def _complex_mpfr_field_(self, field):
-        return field(self._expr)
-
-    def _complex_double_(self, C):
-        return C(self._expr)
-
-    def _real_double_(self, R):
-        return R(self._expr)
-
-    # TODO: should len(args) == len(vars)?
-    def __call__(self, *args):
-        vars = self.args()
-        dct = dict( (vars[i], args[i]) for i in range(len(args)) )
-        return self._expr.substitute(dct)
-
-    def _repr_(self, simplify=True):
-        args = self.args()
-        if len(args) == 1:
-            return "%s |--> %s" % (args[0], self._expr._repr_(simplify=simplify))
-        else:
-            args = ", ".join(map(str, args))
-            return "(%s) |--> %s" % (args, self._expr._repr_(simplify=simplify))
-
-    def _latex_(self):
-        args = self.args()
-        if len(args) == 1:
-            return "%s \\ {\mapsto}\\ %s" % (args[0],
-                    self._expr._latex_())
-        else:
-            vars = ", ".join(map(latex, args))
-            # the weird TeX is to workaround an apparent JsMath bug
-            return "\\left(%s \\right)\\ {\\mapsto}\\ %s" % (args, self._expr._latex_())
-
-    def _neg_(self):
-        return CallableSymbolicExpression(self.parent(), -self._expr)
-
-    def __add__(self, right):
-        """        
-        EXAMPLES:
-            sage: f(x,n,y) = x^n + y^m;  g(x,n,m,z) = x^n +z^m
-            sage: f + g
-            (x, n, m, y, z) |--> z^m + y^m + 2*x^n
-            sage: g + f
-            (x, n, m, y, z) |--> z^m + y^m + 2*x^n
-        """
-        if isinstance(right, CallableSymbolicExpression):
-            if self.parent() is right.parent():
-                return self._add_(right)
-            else:
-                args = self._unify_args(right)
-                R = CallableSymbolicExpressionRing(args)
-                return R(self) + R(right)
-        else:
-            return RingElement.__add__(self, right)
-
-    def _add_(self, right):
-        return CallableSymbolicExpression(self.parent(), self._expr + right._expr)
-
-    def __sub__(self, right):
-        """
-        EXAMPLES:
-            sage: f(x,n,y) = x^n + y^m;  g(x,n,m,z) = x^n +z^m            
-            sage: f - g
-            (x, n, m, y, z) |--> y^m - z^m
-            sage: g - f
-            (x, n, m, y, z) |--> z^m - y^m
-        """
-        if isinstance(right, CallableSymbolicExpression):
-            if self.parent() is right.parent():
-                return self._sub_(right)
-            else:
-                args = self._unify_args(right)
-                R = CallableSymbolicExpressionRing(args)
-                return R(self) - R(right)
-        else:
-            return RingElement.__sub__(self, right)
-
-    def _sub_(self, right):
-        return CallableSymbolicExpression(self.parent(), self._expr - right._expr)
-
-    def __mul__(self, right):
-        """
-        EXAMPLES:
-            sage: f(x) = x+2*y; g(y) = y+3*x
-            sage: f*(2/3)
-            x |--> 2*(2*y + x)/3
-            sage: f*g
-            (x, y) |--> (y + 3*x)*(2*y + x)
-            sage: (2/3)*f
-            x |--> 2*(2*y + x)/3
-            
-            sage: f(x,y,z,a,b) = x+y+z-a-b; f
-            (x, y, z, a, b) |--> z + y + x - b - a
-            sage: f * (b*c)
-            (x, y, z, a, b) |--> b*c*(z + y + x - b - a)
-            sage: g(x,y,w,t) = x*y*w*t
-            sage: f*g
-            (x, y, a, b, t, w, z) |--> t*w*x*y*(z + y + x - b - a)
-            sage: (f*g)(2,3)
-            6*t*w*(z - b - a + 5)
-
-            sage: f(x,n,y) = x^n + y^m;  g(x,n,m,z) = x^n +z^m
-            sage: f * g
-            (x, n, m, y, z) |--> (y^m + x^n)*(z^m + x^n)
-            sage: g * f
-            (x, n, m, y, z) |--> (y^m + x^n)*(z^m + x^n)
-        """
-        if isinstance(right, CallableSymbolicExpression):
-            if self.parent() is right.parent():
-                return self._mul_(right)
-            else:
-                args = self._unify_args(right)
-                R = CallableSymbolicExpressionRing(args)
-                return R(self)*R(right)
-        else:
-            return RingElement.__mul__(self, right)
-
-    def _mul_(self, right):
-        return CallableSymbolicExpression(self.parent(), self._expr * right._expr)
-
-    def __div__(self, right):
-        """
-        EXAMPLES:
-
-            sage: f(x,n,y) = x^n + y^m;  g(x,n,m,z) = x^n +z^m            
-            sage: f / g
-            (x, n, m, y, z) |--> (y^m + x^n)/(z^m + x^n)
-            sage: g / f
-            (x, n, m, y, z) |--> (z^m + x^n)/(y^m + x^n)
-        """
-        if isinstance(right, CallableSymbolicExpression):
-            if self.parent() is right.parent():
-                return self._div_(right)
-            else:
-                args = self._unify_args(right)
-                R = CallableSymbolicExpressionRing(args)
-                return R(self) / R(right)
-        else:
-            return RingElement.__div__(self, right)
-
-    def _div_(self, right):
-        return CallableSymbolicExpression(self.parent(), self._expr / right._expr)
-    
-    def __pow__(self, right):
-        return CallableSymbolicExpression(self.parent(), self._expr ** right)
-
-    def _unify_args(self, x):
-        r"""
-        Takes the variable list from another CallableSymbolicExpression object and
-        compares it with the current CallableSymbolicExpression object's variable list,
-        combining them according to the following rules:
-
-        Let \code{a} be \code{self}'s variable list, let \code{b} be
-        \code{y}'s variable list. 
-        
-        \begin{enumerate}
-
-        \item If \code{a == b}, then the variable lists are identical,
-              so return that variable list.
-
-        \item If \code{a} $\neq$ \code{b}, then check if the first $n$
-              items in \code{a} are the first $n$ items in \code{b},
-              or vice-versa. If so, return a list with these $n$
-              items, followed by the remaining items in \code{a} and
-              \code{b} sorted together in alphabetical order.
-        
-        \end{enumerate}
-
-        Note: When used for arithmetic between CallableSymbolicExpressions,
-        these rules ensure that the set of CallableSymbolicExpressions will have
-        certain properties.  In particular, it ensures that the set is
-        a \emph{commutative} ring, i.e., the order of the input
-        variables is the same no matter in which order arithmetic is
-        done.
-
-        INPUT:
-            x -- A CallableSymbolicExpression
-
-        OUTPUT:
-            A tuple of variables.
-        
-        EXAMPLES:
-            sage: f(x, y, z) = sin(x+y+z)
-            sage: f
-            (x, y, z) |--> sin(z + y + x)
-            sage: g(x, y) = y + 2*x
-            sage: g
-            (x, y) |--> y + 2*x
-            sage: f._unify_args(g)
-            (x, y, z)
-            sage: g._unify_args(f)
-            (x, y, z)
-
-            sage: f(x, y, z) = sin(x+y+z)
-            sage: g(w, t) = cos(w - t)
-            sage: g
-            (w, t) |--> cos(w - t)
-            sage: f._unify_args(g)
-            (t, w, x, y, z)
-
-            sage: f(x, y, t) = y*(x^2-t)
-            sage: f
-            (x, y, t) |--> (x^2 - t)*y
-            sage: g(x, y, w) = x + y - cos(w)
-            sage: f._unify_args(g)
-            (x, y, t, w)
-            sage: g._unify_args(f)
-            (x, y, t, w)
-            sage: f*g
-            (x, y, t, w) |--> (x^2 - t)*y*(y + x - cos(w))
-            
-            sage: f(x,y, t) = x+y
-            sage: g(x, y, w) = w + t
-            sage: f._unify_args(g)
-            (x, y, t, w)
-            sage: g._unify_args(f)
-            (x, y, t, w)
-            sage: f + g
-            (x, y, t, w) |--> y + x + w + t
-
-        AUTHORS:
-            -- Bobby Moretti, thanks to William Stein for the rules
-
-        """
-        a = self.args()
-        b = x.args()
-
-        # Rule #1
-        if [str(x) for x in a] == [str(x) for x in b]:
-            return a
-
-        # Rule #2
-        new_list = []
-        done = False
-        i = 0
-        while not done and i < min(len(a), len(b)):
-            if var_cmp(a[i], b[i]) == 0:
-                new_list.append(a[i])
-                i += 1
-            else:
-                done = True
-        
-        temp = set([])
-        # Sorting remaining variables.
-        for j in range(i, len(a)):
-            if not a[j] in temp:
-                temp.add(a[j])
-        
-        for j in range(i, len(b)):
-            if not b[j] in temp:
-                temp.add(b[j])
-
-        temp = list(temp)
-        temp.sort(var_cmp)
-        new_list.extend(temp)
-        return tuple(new_list)
-
-
-#########################################################################################
-#  End callable functions
-#########################################################################################
-
-class SymbolicComposition(SymbolicOperation):
-    r"""
-    Represents the symbolic composition of $f \circ g$.
-    """
-    def __init__(self, f, g):
-        """
-        INPUT:
-            f, g -- both must be in the symbolic expression ring.
-        """
-        SymbolicOperation.__init__(self, [f,g])
-
-    def _recursive_sub(self, kwds):
-        ops = self._operands
-        return ops[0](ops[1]._recursive_sub(kwds))
-    
-    def _recursive_sub_over_ring(self, kwds, ring):
-        ops = self._operands
-        return ring(ops[0](ops[1]._recursive_sub_over_ring(kwds, ring=ring)))
+        v = SymbolicVariable(s)
+        _vars[s] = v
+        return v
+
+_syms = {}
+
+t = var('t')
+x = var('x')
+y = var('y')
+z = var('z')
+w = var('w')
+
+class Function_sin(PrimitiveFunction):
+    '''
+    The sine function
+    '''
+    def _repr_(self):
+        return "sin"
+
+    def _latex_(self):
+        return "\\sin"
 
     def _is_atomic(self):
         return True
 
-    def _repr_(self, simplify=True):
-        if simplify:
-            if hasattr(self, '_simp'):
-                return self._simp._repr_(simplify=False)
-            else:
-                return self.simplify()._repr_(simplify=False)
-        ops = self._operands
-        return "%s(%s)"% (ops[0]._repr_(simplify=False), ops[1]._repr_(simplify=False))
-
-    def _latex_(self):
-        if not self.is_simplified():
-            return self.simplify()._latex_()
-        ops = self._operands
-        # certain functions (such as \sqrt) need braces in LaTeX
-        if (ops[0]).tex_needs_braces():
-            return r"%s{ %s }" % ( (ops[0])._latex_(), (ops[1])._latex_())
-        # ... while others (such as \cos) don't
-        return r"%s \left( %s \right)"%((ops[0])._latex_(),(ops[1])._latex_())
-
-    def _maxima_init_(self):
-        ops = self._operands
-        return '%s(%s)' % (ops[0]._maxima_init_(), ops[1]._maxima_init_())
-
-    def _sys_init_(self, system):
-        ops = self._operands
-        return '%s(%s)' % (sys_init(ops[0],system), sys_init(ops[1],system))
-
-    def _mathematica_init_(self):
-        system = 'mathematica'
-        ops = self._operands
-        return '%s[%s]' % (sys_init(ops[0],system).capitalize(), sys_init(ops[1],system))
-
-    def __float__(self):
-        f = self._operands[0]
-        g = self._operands[1]
-        return float(f._approx_(float(g)))
-
-    def __complex__(self):
-        f = self._operands[0]
-        g = self._operands[1]
-        return complex(f._approx_(float(g)))
-
-    def _mpfr_(self, field):
-        """
-        Coerce to a multiprecision real number.
-        
-        EXAMPLES:
-            sage: RealField(100)(sin(2)+cos(2))
-            0.49315059027853930839845163641
-
-            sage: RR(sin(pi))
-            0.000000000000000
-            
-            sage: type(RR(sqrt(163)*pi))
-            <type 'sage.rings.real_mpfr.RealNumber'>
-
-            sage: RR(coth(pi))
-            1.00374187319732
-            sage: RealField(100)(coth(pi))
-            1.0037418731973212882015526912
-            sage: RealField(200)(acos(1/10))
-            1.4706289056333368228857985121870581235299087274579233690964            
-        """
-        if not self.is_simplified():
-            return self.simplify()._mpfr_(field)
-        f = self._operands[0]
-        g = self._operands[1]
-        x = f(g._mpfr_(field))
-        if isinstance(x, SymbolicExpression):
-            if field.prec() <= 53:
-                return field(float(x))
-            else:
-                raise TypeError, "precision loss"
-        else:
-            return x
-
-
-    def _complex_mpfr_field_(self, field):
-        """
-        Coerce to a multiprecision complex number.
-        
-        EXAMPLES:
-            sage: ComplexField(100)(sin(2)+cos(2)+I)
-            0.49315059027853930839845163641 + 1.0000000000000000000000000000*I
-            
-        """
-        if not self.is_simplified():
-            return self.simplify()._complex_mpfr_field_(field)
-        f = self._operands[0]
-        g = self._operands[1]
-        x = f(g._complex_mpfr_field_(field))
-        if isinstance(x, SymbolicExpression):
-            if field.prec() <= 53:
-                return field(complex(x))
-            else:
-                raise TypeError, "precision loss"
-        else:
-            return x
-
-    def _complex_double_(self, field):
-        """
-        Coerce to a complex double.
-        
-        EXAMPLES:
-            sage: CDF(sin(2)+cos(2)+I)
-            0.493150590279 + 1.0*I
-            sage: CDF(coth(pi))
-            1.0037418732
-        """
-        if not self.is_simplified():
-            return self.simplify()._complex_double_(field)
-        f = self._operands[0]
-        g = self._operands[1]
-        z = f(g._complex_double_(field))
-        if isinstance(z, SymbolicExpression):
-            return field(complex(z))
-        return z
-
-    def _real_double_(self, field):
-        """
-        Coerce to a real double.
-        
-        EXAMPLES:
-            sage: RDF(sin(2)+cos(2))
-            0.493150590279
-        """
-        if not self.is_simplified():
-            return self.simplify()._real_double_(field)
-        f = self._operands[0]
-        g = self._operands[1]
-        z = f(g._real_double_(field))
-        if isinstance(z, SymbolicExpression):
-            return field(float(z))
-        return z
-
-class PrimitiveFunction(SymbolicExpression):
-    def __init__(self, needs_braces=False):
-        self._tex_needs_braces = needs_braces
-
-    def plot(self, *args, **kwds):
-        f = self(var('x'))
-        return SymbolicExpression.plot(f, *args, **kwds)
+sin = Function_sin()
+_syms['sin'] = sin
+
+class Function_cos(PrimitiveFunction):
+    '''
+    The cosine function
+    '''
+    def _repr_(self):
+        return "cos"
+
+    def _latex_(self):
+        return "\\cos"
 
     def _is_atomic(self):
         return True
-
-    def tex_needs_braces(self):
-        return self._tex_needs_braces
-
-    def __call__(self, x, *args):
-        if isinstance(x, float):
-            return self._approx_(x)
-        try:
-            return getattr(x, self._repr_())(*args)
-        except AttributeError:
-            return SymbolicComposition(self, SR(x))
-
-    def _approx_(self, x):  # must *always* be called with a float x as input.
-        s = '%s(%s), numer'%(self._repr_(), float(x))
-        return float(maxima.eval(s))
-
-_syms = {}
-
-class Function_erf(PrimitiveFunction):
-    r"""
-    The error function, defined as $\text{erf}(x) =
-    \frac{2}{\sqrt{\pi}}\int_0^x e^{-t^2} dt$.
-    """
-
-    def _repr_(self, simplify=True):
-        return "erf"
-
-    def _latex_(self):
-        return "\\text{erf}"
-
-    def _approx_(self, x):
-        return float(1 - pari(float(x)).erfc())
     
-
-erf = Function_erf()
-_syms['erf'] = erf
-
-class Function_abs(PrimitiveFunction):
-    """
-    The absolute value function.
-
-    EXAMPLES:
-        sage: abs(x)
-        abs(x)
-        sage: abs(x^2 + y^2)
-        y^2 + x^2
-        sage: abs(-2)
-        2
-        sage: sqrt(x^2)
-        abs(x)
-        sage: abs(sqrt(x))
-        sqrt(x)        
-    """
-    def _repr_(self, simplify=True):
-        return "abs"
-
-    def _latex_(self):
-        return "\\abs"
-
-    def _approx_(self, x):
-        return float(x.__abs__())
-
-    def __call__(self, x): # special case
-        return SymbolicComposition(self, SR(x))
-
-abs_symbolic = Function_abs()
-_syms['abs'] = abs_symbolic
-
-
-
-class Function_ceil(PrimitiveFunction):
-    """
-    The ceiling function.
-
-    EXAMPLES:
-        sage: a = ceil(2/5 + x)
-        sage: a
-        ceil(x + 2/5)
-        sage: a(4)
-        5
-        sage: a(4.0)
-        5
-        sage: ZZ(a(3))
-        4
-        sage: a = ceil(x^3 + x + 5/2)
-        sage: a
-        ceil(x^3 + x + 1/2) + 2
-        sage: a(x=2)
-        13
-
-        sage: ceil(5.4)
-        6
-        sage: type(ceil(5.4))
-        <type 'sage.rings.integer.Integer'>        
-    """
-    def _repr_(self, simplify=True):
-        return "ceil"
-
-    def _latex_(self):
-        return "\\text{ceil}"
-
-    def _maxima_init_(self):
-        return "ceiling"
-
-    _approx_ = math.ceil
-
-    def __call__(self, x):
-        try:
-            return x.ceil()
-        except AttributeError:
-            if isinstance(x, float):
-                return math.ceil(x)
-        return SymbolicComposition(self, SR(x))
-
-ceil = Function_ceil()
-_syms['ceiling'] = ceil   # spelled ceiling in maxima
-
-
-class Function_floor(PrimitiveFunction):
-    """
-    The floor function.
-
-    EXAMPLES:
-        sage: floor(5.4)
-        5
-        sage: type(floor(5.4))
-        <type 'sage.rings.integer.Integer'>
-        sage: a = floor(5.4 + x); a
-        floor(x + 0.4000000000000004) + 5
-        sage: a(2)
-        7        
-    """
-    def _repr_(self, simplify=True):
-        return "floor"
-
-    def _latex_(self):
-        return "\\text{floor}"
-
-    def _maxima_init_(self):
-        return "floor"
-
-    _approx_ = math.floor
-
-    def __call__(self, x):
-        try:
-            return x.floor()
-        except AttributeError:
-            if isinstance(x, float):
-                return math.floor(x)
-        return SymbolicComposition(self, SR(x))
-
-floor = Function_floor()
-_syms['floor'] = floor   # spelled ceiling in maxima
-
-
-class Function_sin(PrimitiveFunction):
-    """
-    The sine function
-    """
-    def _repr_(self, simplify=True):
-        return "sin"
-
-    def _latex_(self):
-        return "\\sin"
-
-    _approx_ = math.sin
-
-    def __call__(self, x):
-        try:
-            return x.sin()
-        except AttributeError:
-            if isinstance(x, float):
-                return math.sin(x)
-        return SymbolicComposition(self, SR(x))
-
-sin = Function_sin()
-_syms['sin'] = sin
-
-class Function_cos(PrimitiveFunction):
-    """
-    The cosine function
-    """
-    def _repr_(self, simplify=True):
-        return "cos"
-
-    def _latex_(self):
-        return "\\cos"
-
-    _approx_ = math.cos
-
-    def __call__(self, x):
-        try:
-            return x.cos()
-        except AttributeError:
-            if isinstance(x, float):
-                return math.cos(x)
-        return SymbolicComposition(self, SR(x))
-
-   
 cos = Function_cos()
 _syms['cos'] = cos
 
 class Function_sec(PrimitiveFunction):
-    """
+    '''
     The secant function
-
-    EXAMPLES:
-        sage: sec(pi/4)
-        sqrt(2)
-        sage: RR(sec(pi/4))
-        1.41421356237310
-        sage: sec(1/2)
-        sec(1/2)
-        sage: sec(0.5)
-        1.139493927324549
-    """
-    def _repr_(self, simplify=True):
+    '''
+    def _repr_(self):
         return "sec"
 
     def _latex_(self):
         return "\\sec"
-
-    def _approx_(self, x):
-        return 1/math.cos(x)
 
 sec = Function_sec()
 _syms['sec'] = sec
 
-class Function_tan(PrimitiveFunction):
-    """
-    The tangent function
-
-    EXAMPLES:
-        sage: tan(pi)
-        0
-        sage: tan(3.1415)
-        -0.0000926535900581913
-        sage: tan(3.1415/4)
-        0.999953674278156
-        sage: tan(pi/4)
-        1
-        sage: tan(1/2)
-        tan(1/2)
-        sage: RR(tan(1/2))
-        0.546302489843790
-    """
-    def _repr_(self, simplify=True):
-        return "tan"
-
-    def _latex_(self):
-        return "\\tan"
-
-    def _approx_(self, x):
-        return math.tan(x)
-
-tan = Function_tan()
-_syms['tan'] = tan
-
-def atan2(y, x):
-    return atan(y/x)
-
-_syms['atan2'] = atan2
-
-class Function_asin(PrimitiveFunction):
-    """
-    The arcsine function
-
-    EXAMPLES:
-        sage: asin(0.5)
-        0.523598775598299
-        sage: asin(1/2)
-        pi/6
-        sage: asin(1 + I*1.0)
-        1.061275061905036*I + 0.6662394324925153
-    """
-    def _repr_(self, simplify=True):
-        return "asin"
-
-    def _latex_(self):
-        return "\\sin^{-1}"
-
-    def _approx_(self, x):
-        return math.asin(x)
-
-asin = Function_asin()
-_syms['asin'] = asin
-
-class Function_acos(PrimitiveFunction):
-    """
-    The arccosine function
-
-    EXAMPLES:
-        sage: acos(0.5)
-        1.04719755119660
-        sage: acos(1/2)
-        pi/3
-        sage: acos(1 + I*1.0)
-        0.9045568943023813 - 1.061275061905036*I
-    """
-    def _repr_(self, simplify=True):
-        return "acos"
-
-    def _latex_(self):
-        return "\\cos^{-1}"
-
-    def _approx_(self, x):
-        return math.acos(x)
-
-acos = Function_acos()
-_syms['acos'] = acos
-
-
-class Function_atan(PrimitiveFunction):
-    """
-    The arctangent function.
-
-    EXAMPLES:
-        sage: atan(1/2)
-        atan(1/2)
-        sage: RDF(atan(1/2))
-        0.463647609001
-        sage: atan(1 + I)
-        atan(I + 1)
-    """
-    def _repr_(self, simplify=True):
-        return "atan"
-
-    def _latex_(self):
-        return "\\tan^{-1}"
-
-    def _approx_(self, x):
-        return math.atan(x)
-
-atan = Function_atan()
-_syms['atan'] = atan
-
-
-#######
-# Hyperbolic functions
-#######
-
-#tanh
-class Function_tanh(PrimitiveFunction):
-    """
-    The hyperbolic tangent function.
-
-    EXAMPLES:
-        sage: tanh(pi)
-        tanh(pi)
-        sage: tanh(3.1415)
-        0.996271386633702
-        sage: float(tanh(pi))       # random low-order bits
-        0.99627207622074987
-        sage: tan(3.1415/4)
-        0.999953674278156
-        sage: tanh(pi/4)
-        tanh(pi/4)
-        sage: RR(tanh(1/2))
-        0.462117157260010
-        
-        sage: CC(tanh(pi + I*e))
-        0.997524731976164 - 0.00279068768100315*I
-        sage: ComplexField(100)(tanh(pi + I*e))
-        0.99752473197616361034204366446 - 0.0027906876810031453884245163923*I
-        sage: CDF(tanh(pi + I*e))
-        0.997524731976 - 0.002790687681*I
-    """
-    def _repr_(self, simplify=True):
-        return "tanh"
-
-    def _latex_(self):
-        return "\\tanh"
-
-    def _approx_(self, x):
-        return math.tanh(x)
-
-tanh = Function_tanh()
-_syms['tanh'] = tanh
-
-#sinh
-class Function_sinh(PrimitiveFunction):
-    """
-    The hyperbolic sine function.
-
-    EXAMPLES:
-        sage: sinh(pi)
-        sinh(pi)
-        sage: sinh(3.1415)
-        11.5476653707437
-        sage: float(sinh(pi))
-        11.548739357257748
-        sage: RR(sinh(pi))
-        11.5487393572577        
-    """
-    def _repr_(self, simplify=True):
-        return "sinh"
-
-    def _latex_(self):
-        return "\\sinh"
-
-    def _approx_(self, x):
-        return math.sinh(x)
-
-sinh = Function_sinh()
-_syms['sinh'] = sinh
-
-#cosh
-class Function_cosh(PrimitiveFunction):
-    """
-    The hyperbolic cosine function.
-
-    EXAMPLES:
-        sage: cosh(pi)
-        cosh(pi)
-        sage: cosh(3.1415)
-        11.5908832931176
-        sage: float(cosh(pi))
-        11.591953275521519        
-        sage: RR(cosh(1/2))
-        1.12762596520638
-    """
-    def _repr_(self, simplify=True):
-        return "cosh"
-
-    def _latex_(self):
-        return "\\cosh"
-
-    def _approx_(self, x):
-        return math.cosh(x)
-
-cosh = Function_cosh()
-_syms['cosh'] = cosh
-
-#coth
-class Function_coth(PrimitiveFunction):
-    """
-    The hyperbolic cotangent function.
-
-    EXAMPLES:
-        sage: coth(pi)
-        coth(pi)
-        sage: coth(3.1415)
-        1.00374256795520
-        sage: float(coth(pi))
-        1.0037418731973213
-        sage: RR(coth(pi))
-        1.00374187319732
-    """
-    def _repr_(self, simplify=True):
-        return "coth"
-
-    def _latex_(self):
-        return "\\coth"
-
-    def _approx_(self, x):
-        return 1/math.tanh(x)
-
-coth = Function_coth()
-_syms['coth'] = coth
-
-#sech
-class Function_sech(PrimitiveFunction):
-    """
-    The hyperbolic secant function.
-
-    EXAMPLES:
-        sage: sech(pi)        
-        sech(pi)
-        sage: sech(3.1415)
-        0.0862747018248192
-        sage: float(sech(pi))
-        0.086266738334054432
-        sage: RR(sech(pi))
-        0.0862667383340544
-    """
-    def _repr_(self, simplify=True):
-        return "sech"
-
-    def _latex_(self):
-        return "\\sech"
-
-    def _approx_(self, x):
-        return 1/math.cosh(x)
-
-sech = Function_sech()
-_syms['sech'] = sech
-
-
-#csch
-class Function_csch(PrimitiveFunction):
-    """
-    The hyperbolic cosecant function.
-
-    EXAMPLES:
-        sage: csch(pi)
-        csch(pi)
-        sage: csch(3.1415)
-        0.0865975907592133
-        sage: float(csch(pi))
-        0.086589537530046945
-        sage: RR(csch(pi))
-        0.0865895375300470
-    """
-    def _repr_(self, simplify=True):
-        return "csch"
-
-    def _latex_(self):
-        return "\\csch"
-
-    def _approx_(self, x):
-        return 1/math.sinh(x)
-
-csch = Function_csch()
-_syms['csch'] = csch
-
-#############
-# log and exp
-#############
-
 class Function_log(PrimitiveFunction):
-    """
-    The log funtion.
-
-    EXAMPLES:
-        sage: log(e^2)
-        2 
-        sage: log(1024, 2) # the following is ugly (for now)
-        log(1024)/log(2)
-        sage: log(10, 4)
-        log(10)/log(4)
-
-        sage: RDF(log(10,2))
-        3.32192809489
-        sage: RDF(log(8, 2))
-        3.0
-        sage: log(RDF(10))
-        2.30258509299
-        sage: log(2.718)
-        0.999896315728952
-    """
-    def __init__(self):
-        PrimitiveFunction.__init__(self)
-
-    def _repr_(self, simplify=True):
+    '''
+    The log function
+    '''
+    def _repr_(self):
         return "log"
-        
+
     def _latex_(self):
         return "\\log"
 
-    _approx_ = math.log
-
-function_log = Function_log()
-ln = function_log
-
-def log(x, base=None):
-    if base is None:
-        try:
-            return x.log()
-        except AttributeError: 
-            return function_log(x)
-    else:
-        try:
-            return x.log(base)
-        except AttributeError:
-            return function_log(x) / function_log(base)
-
-class Function_sqrt(PrimitiveFunction):
-    """
-    The square root function.
-
-    EXAMPLES:
-        sage: sqrt(-1)
-        I
-        sage: sqrt(2)
-        sqrt(2)
-        sage: sqrt(x^2)
-        abs(x)
-    """
-    def __init__(self):
-        PrimitiveFunction.__init__(self, needs_braces=True)
-    
-    def _repr_(self, simplify=True):
-        return "sqrt"
-
-    def _latex_(self):
-        return "\\sqrt"
-
-    def __call__(self, x):
-        # if x is an integer or rational, never call the sqrt method
-        if isinstance(x, float):
-            return self._approx_(x)
-        if not isinstance(x, (Integer, Rational)):
-            try:
-                return x.sqrt()
-            except AttributeError:
-                pass
-        return SymbolicComposition(self, SR(x))
-    
-
-    def _approx_(self, x):
-        return math.sqrt(x)
-
-sqrt = Function_sqrt()
-_syms['sqrt'] = sqrt
-
-class Function_exp(PrimitiveFunction):
-    """
-    The square root function.
-
-    EXAMPLES:
-        sage: exp(-1)
-        e^-1
-        sage: exp(2)
-        e^2
-        sage: exp(x^2 + log(x))
-        x*e^x^2
-        sage: exp(2.5)
-        12.1824939607035
-        sage: exp(float(2.5))
-        12.182493960703473
-        sage: exp(RDF('2.5'))
-        12.1824939607
-    """
-    def __init__(self):
-        PrimitiveFunction.__init__(self, needs_braces=True)
-    
-    def _repr_(self, simplify=True):
-        return "exp"
-
-    def _latex_(self):
-        return "\\exp"
-
-    def __call__(self, x):
-        # if x is an integer or rational, never call the sqrt method
-        if isinstance(x, float):
-            return self._approx_(x)
-        if not isinstance(x, (Integer, Rational)):
-            try:
-                return x.exp()
-            except AttributeError:
-                pass
-        return SymbolicComposition(self, SR(x))
-    
-
-    def _approx_(self, x):
-        return math.exp(x)
-
-exp = Function_exp()
-_syms['exp'] = exp
-
+log = Function_log()
+_syms['log'] = log
 
 #######################################################
-# Symbolic functions
-#######################################################
-
-class SymbolicFunction(PrimitiveFunction):
-    """
-    A formal symbolic function.
-
-    EXAMPLES:
-        sage: f = function('foo')
-        sage: g = f(x,y,z)
-        sage: g
-        foo(x, y, z)
-        sage: g(x=var('theta'))
-        foo(theta, y, z)
-    """
-    def __init__(self, name):
-        PrimitiveFunction.__init__(self, needs_braces=True)
-        self._name = str(name)
-    
-    def _repr_(self, simplify=True):
-        return self._name
-
-    def _is_atomic(self):
-        return True
-
-    def _latex_(self):
-        return "{\\rm %s}"%self._name
-
-    def _maxima_init_(self):
-        return "'%s"%self._name
-
-    def _approx_(self, x):
-        raise TypeError
-
-    def __call__(self, *args):
-        return SymbolicFunctionEvaluation(self, [SR(x) for x in args])
-
-class SymbolicFunction_delayed(SymbolicFunction):
-    def simplify(self):
-        return self
-
-    def is_simplified(self):
-        return True
-
-    def _maxima_init_(self):
-        return "%s"%self._name
-
-    def __call__(self, *args):
-        return SymbolicFunctionEvaluation_delayed(self, [SR(x) for x in args])
-    
-    
-
-class SymbolicFunctionEvaluation(SymbolicExpression):
-    """
-    The result of evaluating a formal symbolic function.
-
-    EXAMPLES:
-        sage: h = function('gfun', x); h
-        gfun(x)
-        sage: k = h.integral(x); k
-        integrate(gfun(x), x)
-        sage: k(gfun=sin)
-        -cos(x)
-        sage: k(gfun=cos)
-        sin(x)
-        sage: k.diff(x)
-        gfun(x)
-    """
-    def __init__(self, f, args):
-        """
-        INPUT:
-            f -- symbolic function
-            args -- a tuple or list of symbolic expressions, at which
-                    f is formally evaluated.
-        """
-        SymbolicExpression.__init__(self)
-        self._f = f
-        if not isinstance(args, tuple):
-            args = tuple(args)
-        self._args = args
-
-    def _is_atomic(self):
-        return True
-
-    def arguments(self):
-        return tuple(self._args)
-    
-    def _repr_(self, simplify=True):
-        if simplify:
-            return self.simplify()._repr_(simplify=False)
-        else:
-            return '%s(%s)'%(self._f._name, ', '.join([x._repr_(simplify=simplify)
-                                                       for x in self._args]))
-
-    def _latex_(self):
-        return "{\\rm %s}(%s)"%(self._f._name, ', '.join([x._latex_() for
-                                                       x in self._args]))
-
-    def _maxima_init_(self):
-        try:
-            return self.__maxima_init
-        except AttributeError:
-            n = self._f._name
-            if not (n in ['integrate', 'diff']):
-                n = "'" + n
-            s = "%s(%s)"%(n, ', '.join([x._maxima_init_()
-                                           for x in self._args]))
-            self.__maxima_init = s
-        return s
-
-    def _recursive_sub(self, kwds):
-        """
-        EXAMPLES:
-            sage: f = function('foo',x); f
-            foo(x)
-            sage: f(foo=sin)
-            sin(x)
-            sage: f(x+y)
-            foo(y + x)
-            sage: a = f(pi)
-            sage: a.substitute(foo = sin)
-            0
-            sage: a = f(pi/2)
-            sage: a.substitute(foo = sin)
-            1
-            sage: b = f(pi/3) + x + y
-            sage: b
-            y + x + foo(pi/3)
-            sage: b(foo = sin)
-            y + x + sqrt(3)/2
-            sage: b(foo = cos)
-            y + x + 1/2
-            sage: b(foo = cos, x=y)
-            2*y + 1/2
-        """
-        function_sub = False
-        for x in kwds.keys():
-            if repr(x) == self._f._name:
-                g = kwds[x]
-                function_sub = True
-                break
-        if function_sub:
-            del kwds[x]
-
-        arg = tuple([SR(x._recursive_sub(kwds)) for x in self._args])
-
-        if function_sub:
-            return g(*arg)
-        else:
-            return self.__class__(self._f, arg)
-
-    def _recursive_sub_over_ring(self, kwds, ring):
-        raise TypeError, "no way to coerce the formal function to ring."
-
-    def variables(self):
-        """
-        Return the variables appearing in the simplified form of self.
-        
-        EXAMPLES:
-            sage: foo = function('foo')
-            sage: w = foo(x,y,a,b,z) + t
-            sage: w
-            foo(x, y, a, b, z) + t
-            sage: w.variables()
-            (a, b, t, x, y, z)
-        """
-        try:
-            return self.__variables
-        except AttributeError:
-            pass
-        vars = sum([list(op.variables()) for op in self._args], [])
-        vars.sort(var_cmp)
-        vars = tuple(vars)
-        self.__variables = vars
-        return vars
-
-class SymbolicFunctionEvaluation_delayed(SymbolicFunctionEvaluation):
-    def simplify(self):
-        return self
-
-    def is_simplified(self):
-        return True
-
-    def __float__(self):
-        return float(self._maxima_())
-
-    def __complex__(self):
-        return complex(self._maxima_())
-
-    def _real_double_(self, R):
-        return R(float(self))
-
-    def _complex_double_(self, C):
-        return C(float(self))
-
-    def _mpfr_(self, field):
-        if field.prec() <= 53:
-            return field(float(self))
-        raise TypeError
-
-    def _complex_mpfr_field_(self, field):
-        if field.prec() <= 53:
-            return field(float(self))
-        raise TypeError
-
-    def _maxima_init_(self):
-        try:
-            return self.__maxima_init
-        except AttributeError:
-            n = self._f._name
-            s = "%s(%s)"%(n, ', '.join([x._maxima_init_()
-                                           for x in self._args]))
-            self.__maxima_init = s
-        return s
-    
-
-    
-_functions = {}
-def function(s, *args):
-    """
-    Create a formal symbolic function with the name \emph{s}.
-
-    EXAMPLES:
-        sage: f = function('cr', a)
-        sage: g = f.diff(a).integral(b)
-        sage: g
-        diff(cr(a), a, 1)*b
-        sage: g(cr=cos)
-        -sin(a)*b
-        sage: g(cr=sin(x) + cos(x))
-        (cos(a) - sin(a))*b
-    """
-    if len(args) > 0:
-        return function(s)(*args)
-    if isinstance(s, SymbolicFunction):
-        return s
-    s = str(s)
-    if ',' in s:
-        return tuple([function(x.strip()) for x in s.split(',')])
-    elif ' ' in s:
-        return tuple([function(x.strip()) for x in s.split()])
-    try:
-        X = _functions[s]()
-        if not X is None:
-            return X
-    except KeyError:
-        pass
-    v = SymbolicFunction(s)
-    _functions[s] = weakref.ref(v)
-    return v
-    
-#######################################################
-
-
-
-
-#######################################################
-
-symtable = {'%pi':'pi', '%e': 'e', '%i':'I', '%gamma':'euler_gamma'}
-
-from sage.rings.infinity import infinity, minus_infinity
-
-_syms['inf'] = infinity
-_syms['minf'] = minus_infinity
-
-from sage.misc.multireplace import multiple_replace
-
-maxima_tick = re.compile("'[a-z|A-Z|0-9|_]*")
-
-maxima_qp = re.compile("\?\%[a-z|A-Z|0-9|_]*")  # e.g., ?%jacobi_cd
-
-maxima_var = re.compile("\%[a-z|A-Z|0-9|_]*")  # e.g., ?%jacobi_cd
-
-def symbolic_expression_from_maxima_string(x, equals_sub=False, maxima=maxima):
+symtable = {'%pi':'_Pi_', '%e': '_E_', '%i':'_I_'}
+import sage.functions.constants as c
+_syms['_Pi_'] = SER(c.Pi)
+_syms['_E_'] = SER(c.E)
+_syms['_I_'] = SER(CC.gen(0))  # change when we create a symbolic I.
+
+def symbolic_expression_from_maxima_string(x):
     global _syms
-
-    if len(x) == 0:
-        raise RuntimeError, "invalid symbolic expression -- ''"
-    maxima.set('_tmp_',x)
-
-    # This is inefficient since it so rarely is needed:
-    #r = maxima._eval_line('listofvars(_tmp_);')[1:-1]
-    
-    s = maxima._eval_line('_tmp_;')
-
-    formal_functions = maxima_tick.findall(s)
-    if len(formal_functions) > 0:
-        for X in formal_functions:
-            _syms[X[1:]] = function(X[1:])
-        # You might think there is a potential very subtle bug if 'foo is in a string literal --
-        # but string literals should *never* ever be part of a symbolic expression.
-        s = s.replace("'","")  
-
-    delayed_functions = maxima_qp.findall(s)
-    if len(delayed_functions) > 0:
-        for X in delayed_functions:
-            _syms[X[2:]] = SymbolicFunction_delayed(X[2:])
-        s = s.replace("?%","")
-
-    s = multiple_replace(symtable, s)
-    s = s.replace("%","")
-
-    if equals_sub:
-        s = s.replace('=','==')
-        
-    global is_simplified
-    try:
-        # use a global flag so all expressions obtained via
-        # evaluation of maxima code are assumed pre-simplified
-        is_simplified = True
-        last_msg = ''
-        while True:
-            try:
-                w = sage_eval(s, _syms)
-            except NameError, msg:
-                if msg == last_msg:
-                    raise NameError, msg
-                msg = str(msg)
-                last_msg = msg
-                i = msg.find("'")
-                j = msg.rfind("'")
-                nm = msg[i+1:j]
-                _syms[nm] = var(nm)
-            else:
-                break
-        if isinstance(w, (list, tuple)):
-            return w
-        else:
-            x = SR(w)
-        return x
-    except SyntaxError:
-        raise TypeError, "unable to make sense of Maxima expression '%s' in SAGE"%s
-    finally:
-        is_simplified = False
+    maxima.eval('listdummyvars: false')
+    maxima.eval('_tmp_: %s'%x)
+    r = maxima.eval('listofvars(_tmp_)')[1:-1]
+    if len(r) > 0:
+        # Now r is a list of all the indeterminate variables that
+        # appear in the expression x.
+        v = r.split(',')
+        for a in v:
+            _syms[a] = var(a)
+    s = maxima.eval('_tmp_')
+    for x, y in symtable.iteritems():
+        s = s.replace(x, y)
+    #print s
+    #print _syms
+    return SymbolicExpressionRing(sage_eval(s, _syms))
 
 def symbolic_expression_from_maxima_element(x):
     return symbolic_expression_from_maxima_string(x.name())
 
-def evaled_symbolic_expression_from_maxima_string(x):
-    return symbolic_expression_from_maxima_string(maxima.eval(x))
-
-    
Index: age/calculus/equations.py
===================================================================
--- sage/calculus/equations.py	(revision 4058)
+++ 	(revision )
@@ -1,374 +1,0 @@
-r"""
-Symbolic Equations and Inequalities.
-
-SAGE can solving symbolic equations and expressing inequalities.
-For example, we derive the quadratic formula as follows:
-
-    sage: qe = (a*x^2 + b*x + c == 0)
-    sage: print qe
-                                     2
-                                  a x  + b x + c == 0
-    sage: print solve(qe, x)
-    [
-                                          2
-                                  - sqrt(b  - 4 a c) - b
-                              x == ----------------------
-                                           2 a,
-                                         2
-                                   sqrt(b  - 4 a c) - b
-                               x == --------------------
-                                           2 a
-    ]
-
-AUTHORS:
-    -- Bobby Moretti: initial version
-    -- William Stein: second version
-
-EXAMPLES:
-    sage: f = x^2 + y^2 == 1
-    sage: f.solve(x)
-    [x == (-sqrt(1 - y^2)), x == sqrt(1 - y^2)]
-
-    sage: f = x^5 + a
-    sage: solve(f==0,x)
-    [x == -e^(2*I*pi/5)*a^(1/5), x == -e^(4*I*pi/5)*a^(1/5), x == -e^(-(4*I*pi/5))*a^(1/5), x == -e^(-(2*I*pi/5))*a^(1/5), x == (-a^(1/5))]
-"""
-
-_assumptions = []
-
-from sage.structure.sage_object import SageObject
-from sage.structure.sequence    import Sequence
-from sage.interfaces.maxima     import maxima
-from sage.misc.sage_eval        import sage_eval
-
-import operator
-
-symbols = {operator.lt:' < ', operator.le:' <= ', operator.eq:' == ',
-           operator.ne:' != ',
-            operator.ge:' >= ', operator.gt:' > '}
-
-maxima_symbols = dict(symbols)
-maxima_symbols[operator.eq] = '='
-
-
-latex_symbols = {operator.lt:' < ', operator.le:' \\leq ', operator.eq:' = ',
-                 operator.ne:' \\neq ',
-            operator.ge:' \\geq ', operator.gt:' > '}
-
-comparisons = {operator.lt:set([-1]), operator.le:set([-1,0]), operator.eq:set([0]),
-               operator.ne:set([-1,1]),  operator.ge:set([0,1]), operator.gt:set([1])}
-
-def var_cmp(x,y):
-    return cmp(str(x), str(y))
-
-def paren(x):
-    if x._is_atomic():
-        return repr(x)
-    else:
-        return '(%s)'%repr(x)
-
-class SymbolicEquation(SageObject):
-    def __init__(self, left, right, op):
-        self._left = left
-        self._right = right
-        self._op = op
-
-    def __call__(self, *args, **argv):
-        return self._op(self._left(*args, **argv), self._right(*args,**argv))
-
-    def __cmp__(self, right):
-        """
-        EXAMPLES:
-            sage: (x>0) == (x>0)
-            True
-            sage: (x>0) == (x>1)
-            False
-            sage: (x>0) != (x>1)
-            True
-        """
-        if not isinstance(right, SymbolicEquation):
-            return cmp(type(self), type(right))
-        c = cmp(self._op, right._op)
-        if c: return c
-        i = bool(self._left == right._left)
-        if not i: return -1
-        i = bool(self._right == right._right)
-        if not i: return 1
-        return 0
-
-    def _repr_(self):
-        return "%s%s%s" %(paren(self._left), symbols[self._op], paren(self._right))
-
-    def variables(self):
-        """
-        EXAMPLES:
-            sage: f =  (x+y+w) == (x^2 - y^2 - z^3);   f
-            (y + x + w) == (-z^3 - y^2 + x^2)
-            sage: f.variables()
-            [w, x, y, z]
-        """
-        try:
-            return self.__variables
-        except AttributeError:
-            v = list(set(list(self._left.variables()) + list(self._right.variables())))
-            v.sort(var_cmp)
-            self.__variables = v
-            return v
-
-    def operator(self):
-        return self._op
-
-    def left(self):
-        return self._left
-    lhs = left
-    left_hand_side = left
-
-    def right(self):
-        return self._right
-    rhs = right
-    right_hand_side = right
-
-    def __str__(self):
-        """
-        EXAMPLES:
-            sage: f =  (x^2 - x == 0)
-            sage: f
-            (x^2 - x) == 0
-            sage: print f
-                                               2
-                                              x  - x == 0
-        """
-        s = self._maxima_().display2d(onscreen=False)
-        s = s.replace('%pi','pi').replace('%i',' I').replace('%e', ' e').replace(' = ',' == ')
-        return s
-
-    def _latex_(self):
-        return "%s %s %s" %(self._left._latex_(), latex_symbols[self._op],
-                            self._right._latex_())
-
-    # this is an excellent idea by Robert Bradshaw
-    #def __nonzero__(self):
-    #    result = self._left.__cmp__(self._right)
-    #    return result in comparisons[self._op]
-    def __nonzero__(self):
-        """
-        Return True if this equality is definitely true.  Return False
-        if it is false or the algorithm for testing equality is
-        inconclusive.
-        """
-        m = self._maxima_()
-        try:
-            s = m.parent()._eval_line('is (%s)'%m.name())
-        except TypeError, msg:
-            #raise ValueError, "unable to evaluate the predicate '%s'"%repr(self)
-            return cmp(self._left._maxima_() , self._right._maxima_()) == 0
-        return s == 'true'
-
-    def _maxima_init_(self, maxima=maxima, assume=False):
-        l = self._left._maxima_init_()
-        r = self._right._maxima_init_()
-        if assume and self._op == operator.eq:
-            return 'equal(%s, %s)'%(l, r)
-        return '(%s)%s(%s)' % (l, maxima_symbols[self._op], r)
-
-    def assume(self):
-        if not self in _assumptions:
-            m = self._maxima_init_(assume=True)
-            maxima.assume(m)
-            _assumptions.append(self)
-
-    def forget(self):
-        """
-        Forget the given constraint.
-        """
-        m = self._maxima_()
-        m.parent().forget(m)
-        try:
-            _assumptions.remove(self)
-        except ValueError:
-            pass
-
-    def solve(self, x=None, multiplicities=False):
-        """
-        Symbolically solve for the given variable.
-
-        WARNING: In many cases, only one solution is computed. 
-
-        INPUT:
-            x -- a SymbolicVariable object (if not given, the first in the expression is used)
-            multiplicities -- (default: False) if True, also returns the multiplicities
-                          of each solution, in order. 
-
-        OUTPUT:
-            A list of SymbolicEquations with the variable to solve for on the
-            left hand side.
-
-        EXAMPLES:
-            sage: S = solve(x^3 - 1 == 0, x)
-            sage: S
-            [x == ((sqrt(3)*I - 1)/2), x == ((-sqrt(3)*I - 1)/2), x == 1]
-            sage: S[0]
-            x == ((sqrt(3)*I - 1)/2)
-            sage: S[0].right()
-            (sqrt(3)*I - 1)/2
-
-        We illustrate finding multiplicities of solutions:
-            sage: f = (x-1)^5*(x^2+1)
-            sage: solve(f == 0, x)
-            [x == -1*I, x == I, x == 1]
-            sage: solve(f == 0, x, multiplicities=True)
-            ([x == -1*I, x == I, x == 1], [1, 1, 5])
-            sage: solve(g == 0, x)
-            []            
-        """
-        if not self._op is operator.eq:
-            raise ValueError, "solving only implemented for equalities"
-        if x is None:
-            v = self.variables()
-            if len(v) == 0:
-                if multiplicities:
-                    return [], []
-                else:
-                    return []
-            x = v[0]
-
-        m = self._maxima_()
-        P = m.parent()
-        s = m.solve(x).str()
-
-        X = string_to_list_of_solutions(s)
-        if multiplicities:
-            if len(X) == 0:
-                return X, []
-            else:
-                return X, sage_eval(P.get('multiplicities'))
-        else:
-            return X
-        
-        
-
-def assume(*args):
-    """
-    Make the given assumptions.
-
-    INPUT:
-        *args -- assumptions
-
-    EXAMPLES:
-        sage: assume(x > 0)
-        sage: bool(sqrt(x^2) == x)
-        True
-        sage: forget()
-        sage: bool(sqrt(x^2) == x)
-        False
-    """
-    for x in args:
-        if isinstance(x, (tuple, list)):
-            for y in x:
-                assume(y)
-        else:
-            try:
-                x.assume()
-            except KeyError:
-                raise TypeError, "assume not defined for objects of type '%s'"%type(x)
-
-def forget(*args):
-    """
-    Forget the given assumption, or call with no arguments to forget
-    all assumptions.
-
-    Here an assumption is some sort of symbolic constraint. 
-
-    INPUT:
-        *args -- assumptions (default: forget all assumptions)
-
-    EXAMPLES:
-    We define and forget multiple assumptions:
-        sage: assume(x>0, y>0, z == 1, y>0)
-        sage: assumptions()
-        [x > 0, y > 0, z == 1]
-        sage: forget(x>0, z==1)
-        sage: assumptions()
-        [y > 0]
-    """
-    if len(args) == 0:
-        forget_all()
-        return
-    for x in args:
-        if isinstance(x, (tuple, list)):
-            for y in x:
-                assume(y)
-        else:
-            try:
-                x.forget()
-            except KeyError:
-                raise TypeError, "forget not defined for objects of type '%s'"%type(x)
-
-def assumptions():
-    """
-    List all current symbolic assumptions.
-    
-    EXAMPLES:
-        sage: forget()
-        sage: assume(x^2+y^2 > 0)
-        sage: assumptions()
-        [(y^2 + x^2) > 0]
-        sage: forget(x^2+y^2 > 0)
-        sage: assumptions()
-        []
-        sage: assume(x > y)
-        sage: assume(z > w)
-        sage: assumptions()
-        [x > y, z > w]
-        sage: forget()
-        sage: assumptions()
-        []
-    """
-    return list(_assumptions)
-
-def forget_all():
-    global _assumptions
-    if len(_assumptions) == 0:
-        return
-    maxima._eval_line('forget(facts());')
-    #maxima._eval_line('forget([%s]);'%(','.join([x._maxima_init_() for x in _assumptions])))
-    _assumptions = []
-
-def solve(f, *args, **kwds):
-    """
-    Algebraically solve an equation of system of equations for given variables.
-
-    INPUT:
-        f -- equation or system of equations (given by a list or tuple)
-        *args -- variables to solve for.
-
-    EXAMPLES:
-        sage: solve([x+y==6, x-y==4], x, y)
-        [[x == 5, y == 1]]
-        sage: solve([x^2+y^2 == 1, y^2 == x^3 + x + 1], x, y)
-        [[x == ((-sqrt(3)*I - 1)/2), y == ((-sqrt(3 - sqrt(3)*I))/sqrt(2))],
-         [x == ((-sqrt(3)*I - 1)/2), y == (sqrt(3 - sqrt(3)*I)/sqrt(2))],
-         [x == ((sqrt(3)*I - 1)/2), y == ((-sqrt(sqrt(3)*I + 3))/sqrt(2))],
-         [x == ((sqrt(3)*I - 1)/2), y == (sqrt(sqrt(3)*I + 3)/sqrt(2))],
-         [x == 0, y == -1],
-         [x == 0, y == 1]]
-    """
-    if isinstance(f, (list, tuple)):
-        m = maxima(list(f))
-        try:
-            s = m.solve(args)
-        except:
-            raise ValueError, "Unable to solve %s for %s"%(f, args)
-        a = repr(s)
-        return string_to_list_of_solutions(a)
-    else:
-        return f.solve(*args, **kwds)
-
-import sage.categories.all
-objs = sage.categories.all.Objects()
-
-def string_to_list_of_solutions(s):
-    from sage.calculus.calculus import symbolic_expression_from_maxima_string
-    v = symbolic_expression_from_maxima_string(s, equals_sub=True)
-    return Sequence(v, universe=objs)
-
Index: sage/calculus/functional.py
===================================================================
--- sage/calculus/functional.py	(revision 4059)
+++ sage/calculus/functional.py	(revision 2327)
@@ -1,327 +1,10 @@
-"""
-Functional notation support for common calculus methods.
-"""
+from calculus import SER, SymbolicExpression
 
-from calculus import SR, SymbolicExpression, CallableSymbolicExpression
+def diff(f, *args):
+    if not isinstance(f, SymbolicExpression):
+        f = SER(f)
+    return f.derivative(*args)
 
-def simplify(f):
-    """
-    Simplify the expression f.
-    """
-    try:
-        return f.simplify()
-    except AttributeError:
-        return f
+derivative = diff
 
-def derivative(f, *args, **kwds):
-    """
-    The derivative of f.
-
-    EXAMPLES:
-    We differentiate a callable symbolic function:
-        sage: f(x,y) = x*y + sin(x^2) + e^(-x)
-        sage: f 
-        (x, y) |--> x*y + sin(x^2) + e^(-x)
-        sage: derivative(f, x)
-        (x, y) |--> y + 2*x*cos(x^2) - e^(-x)
-        sage: derivative(f, y)
-        (x, y) |--> x
-
-    We differentiate a polynomial:
-        sage: t = polygen(QQ, 't')
-        sage: f = (1-t)^5; f
-        -t^5 + 5*t^4 - 10*t^3 + 10*t^2 - 5*t + 1
-        sage: derivative(f)
-        -5*t^4 + 20*t^3 - 30*t^2 + 20*t - 5
-
-    We differentiate a symbolic expression:
-        sage: f = exp(sin(a - x^2))/x
-        sage: diff(f, x)
-        -2*cos(x^2 - a)*e^(-sin(x^2 - a)) - (e^(-sin(x^2 - a))/x^2)
-        sage: diff(f, a)
-        cos(x^2 - a)*e^(-sin(x^2 - a))/x        
-    """
-    try:
-        return f.derivative(*args, **kwds)
-    except AttributeError:
-        pass
-    if not isinstance(f, SymbolicExpression):
-        f = SR(f)
-    return f.derivative(*args, **kwds)
-
-diff = derivative
-differentiate = derivative
-
-def integral(f, *args, **kwds):
-    """
-    The integral of f.
-
-    EXAMPLES:
-        sage: integral(sin(x), x)
-        -cos(x)
-        sage: integral(sin(x)^2, x, pi, 123*pi/2)
-        121*pi/4
-        sage: integral( sin(x), x, 0, pi)
-        2
-
-    We integrate a symbolic function:
-        sage: f(x,y) = x*y/z + sin(z)
-        sage: integral(f, z)
-        (x, y) |--> x*y*log(z) - cos(z)
-
-        sage: assume(b-a>0)
-        sage: integral( sin(x), x, a, b)
-        cos(a) - cos(b)
-        sage: forget()
-        
-        sage: print integral(x/(x^3-1), x)
-                                         2 x + 1
-                       2            atan(-------)
-                  log(x  + x + 1)        sqrt(3)    log(x - 1)
-                - --------------- + ------------- + ----------
-                         6             sqrt(3)          3
-                         
-        sage: print integral( exp(-x^2), x )
-                               sqrt( pi) erf(x)
-                               ----------------
-                                      2
-
-    You can have SAGE calculate multiple integrals.  For example,
-    consider the function $exp(y^2)$ on the region between the lines
-    $x=y$, $x=1$, and $y=0$. We find the value of the integral on
-    this region using the command:
-        sage: area = integral(integral(exp(y^2),x,0,y),y,0,1); area
-        e/2 - 1/2
-        sage: float(area)
-        0.85914091422952255
-
-    We compute the line integral of sin(x) along the arc of the curve
-    $x=y^4$ from $(1,-1)$ to $(1,1)$:
-        sage: (x,y) = (t^4,t)
-        sage: (dx,dy) = (diff(x,t), diff(y,t))
-        sage: integral(sin(x)*dx, t,-1, 1)
-        0    
-        sage: restore('x,y')   # restore the symbolic variables x and y
-
-    SAGE is unable to do anything with the following integral:
     
-        sage: print integral( exp(-x^2)*log(x), x )
-                              /      2
-                              [   - x
-                              I  e     log(x) dx
-                              ]
-                              /
-
-    SAGE does not know how to compute this integral either. 
-        sage: print integral( exp(-x^2)*ln(x), x, 0, oo)
-                              inf
-                             /         2
-                             [      - x
-                             I     e     log(x) dx
-                             ]
-                             /
-                              0
-
-    This definite integral is easy:
-        sage: integral( ln(x)/x, x, 1, 2)
-        log(2)^2/2
-
-    SAGE can't do this elliptic integral (yet):
-        sage: integral(1/sqrt(2*t^4 - 3*t^2 - 2), t, 2, 3)
-        integrate(1/(sqrt(2*t^4 - 3*t^2 - 2)), t, 2, 3)
-
-    A double integral:
-        sage: integral(integral(x*y^2, x, 0, y), y, -2, 2)
-        32/5
-
-    This illustrates using assumptions:
-        sage: integral(abs(x), x, 0, 5)
-        25/2
-        sage: integral(abs(x), x, 0, a)
-        integrate(abs(x), x, 0, a)
-        sage: assume(a>0)
-        sage: integral(abs(x), x, 0, a)
-        a^2/2
-        sage: forget()      # forget the assumptions.
-
-    We integrate and differentiate a huge mess:
-        sage: f = (x^2-1+3*(1+x^2)^(1/3))/(1+x^2)^(2/3)*x/(x^2+2)^2
-        sage: g = integral(f, x)
-        sage: h = f - diff(g, x)
-
-    Numerically h is 0, but the symbolic equality checker
-    unfortunately can't tell for sure:
-        sage: print [float(h(i)) for i in range(5)]
-        [0.0, -1.1102230246251565e-16, -8.3266726846886741e-17, -4.163336342344337e-17, -6.9388939039072284e-17]
-        sage: bool(h == 0) 
-        False
-    """
-    try:
-        return f.integral(*args, **kwds)
-    except AttributeError:
-        pass
-    if not isinstance(f, SymbolicExpression):
-        f = SR(f)
-    return f.integral(*args, **kwds)
-
-integrate = integral
-
-def limit(f, dir=None, **argv):
-    """
-    Return the limit as the variable v approaches a from the
-    given direction.
-
-        \begin{verbatim}
-        limit(expr, x = a)
-        limit(expr, x = a, dir='above')
-        \end{verbatim}
-
-    INPUT:
-        dir -- (default: None); dir may have the value `plus' (or 'above')
-               for a limit from above, `minus' (or 'below') for a limit from
-               below, or may be omitted (implying a two-sided
-               limit is to be computed).
-        **argv -- 1 named parameter
-
-    ALIAS: You can also use lim instead of limit. 
-
-    EXAMPLES:
-        sage: limit(sin(x)/x, x=0)
-        1
-        sage: limit(exp(x), x=oo)
-        +Infinity
-        sage: lim(exp(x), x=-oo)
-        0
-        sage: lim(1/x, x=0) 
-        und
-
-    SAGE does not know how to do this limit (which is 0),
-    so it returns it unevaluated:
-        sage: lim(exp(x^2)*(1-erf(x)), x=infinity)
-        limit(e^x^2 - e^x^2*erf(x), x, +Infinity)
-    
-    """
-    if not isinstance(f, SymbolicExpression):
-        f = SR(f)
-    return f.limit(dir=dir, **argv)
-
-lim = limit
-
-def taylor(f, v, a, n):
-    """
-    Expands self in a truncated Taylor or Laurent series in the
-    variable v around the point a, containing terms through $(x - a)^n$.
-
-    INPUT:
-        v -- variable
-        a -- number
-        n -- integer
-
-    EXAMPLES:
-        sage: taylor (sqrt (1 - k^2*sin(x)^2), x, 0, 6)
-        1 - (k^2*x^2/2) - ((3*k^4 - 4*k^2)*x^4/24) - ((45*k^6 - 60*k^4 + 16*k^2)*x^6/720)
-        sage: taylor ((x + 1)^n, x, 0, 4)
-        1 + n*x + (n^2 - n)*x^2/2 + (n^3 - 3*n^2 + 2*n)*x^3/6 + (n^4 - 6*n^3 + 11*n^2 - 6*n)*x^4/24        
-        
-    """
-    if not isinstance(f, SymbolicExpression):
-        f = SR(f)
-    return f.taylor(v=v,a=a,n=n)
-    
-
-def expand(x, *args, **kwds):
-    """
-    EXAMPLES:
-        sage: a = (1+I)*(2-sqrt(3)*I); a
-        (I + 1)*(2 - sqrt(3)*I)
-        sage: expand(a)
-        -sqrt(3)*I + 2*I + sqrt(3) + 2
-        sage: a = (x-1)*(x^2 - 1); a
-        (x - 1)*(x^2 - 1)
-        sage: expand(a)
-        x^3 - x^2 - x + 1
-
-    You can also use expand on polynomial, integer, and other
-    factorizations:
-        sage: x = polygen(ZZ)
-        sage: F = factor(x^12 - 1); F
-        (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + 1) * (x^2 + x + 1) * (x^4 - x^2 + 1)
-        sage: expand(F)
-        x^12 - 1
-        sage: F.expand()
-        x^12 - 1
-        sage: F = factor(2007); F
-        3^2 * 223
-        sage: expand(F)
-        2007
-    
-    Note: If you want to compute the expanded form of a polynomial
-    arithmetic operation quickly and the coefficients of the polynomial
-    all lie in some ring, e.g., the integers, it is vastly faster to
-    create a polynomial ring and do the arithmetic there.
-
-        sage: x = polygen(ZZ)      # polynomial over a given base ring.
-        sage: f = sum(x^n for n in range(5))
-        sage: f*f                  # much faster, even if the degree is huge
-        x^8 + 2*x^7 + 3*x^6 + 4*x^5 + 5*x^4 + 4*x^3 + 3*x^2 + 2*x + 1
-
-    """
-    try:
-        return x.expand(*args, **kwds)
-    except AttributeError:
-        return x
-
-
-def laplace(f, t, s):
-    r"""
-    Attempts to compute and return the Laplace transform of self
-    with respect to the variable t and transform parameter s.  If
-    Laplace cannot find a solution, a delayed function is returned.
-
-    The function that is returned maybe be viewed as a function of s.
-        
-    EXAMPLES:
-        sage: f = exp (2*t + a) * sin(t) * t; f       
-        t*e^(2*t + a)*sin(t)
-        sage: L = laplace(f, t, s); L
-        e^a*(2*s - 4)/((s^2 - 4*s + 5)^2)
-        sage: inverse_laplace(L, s, t)
-        t*e^(2*t + a)*sin(t)
-
-    Unable to compute solution:
-        sage: laplace(1/s, s, t)
-        laplace(1/s, s, t)    
-    """
-    if not isinstance(f, SymbolicExpression):
-        f = SR(f)
-    return f.laplace(t,s)
-
-def inverse_laplace(f, t, s):
-    r"""
-    Attempts to compute and return the inverse Laplace transform of
-    self with respect to the variable t and transform parameter s.  If
-    Laplace cannot find a solution, a delayed function is returned, which
-    is called \code{ilt}.
-
-    EXAMPLES:
-        sage: f = t*cos(t)
-        sage: L = laplace(f, t, s); L
-        2*s^2/(s^2 + 1)^2 - (1/(s^2 + 1))
-        sage: inverse_laplace(L, s, t)
-        t*cos(t)
-        sage: print inverse_laplace(1/(s^3+1), s, t)
-                           sqrt(3) t        sqrt(3) t
-                       sin(---------)   cos(---------)      - t
-                  t/2          2                2          e
-                 e    (-------------- - --------------) + -----
-                          sqrt(3)             3             3
-
-    No explicit inverse Laplace transform, so one is returned formally as a function ilt.
-        sage: inverse_laplace(cos(s), s, t)
-        ilt(cos(s), s, t)
-    """
-    if not isinstance(f, SymbolicExpression):
-        f = SR(f)
-    return f.inverse_laplace(t,s)
-
-
Index: age/calculus/notes.txt
===================================================================
--- sage/calculus/notes.txt	(revision 4057)
+++ 	(revision )
@@ -1,43 +1,0 @@
-On 4/22/07, Ondrej Certik <ondrej.certik@gmail.com> wrote:
-> As to the extensibility  -  I think it would be quite difficult to
-> extend for example Maxima's limits facility (there are some limits
-> that Maxima cannot do, but SymPy can), or Maxima's differential
-> equations solver module. Either it would have to be done in LISP, or
-> rewrite the whole module to python, neither of which I find easy. Or
-> is there a better approach?
-
-I had in mind the following iterative approach:
-
-  (1) Implement the basic limit formulas for products, sums, quotients, etc.,
-        in Python. 
-  (2) This reduces computing limits of symbolic expressions to computing
-        the limits of the leaves in the tree, i.e., symbolic variables, constants, and 
-        primitive functions (like sinh, exp, log, erf).
- (3)  Limits of symbolic variables and constants are trivial.
- (4) For some special functions one writes an optional method _limit_
-       that computes the limit of that special function at a point from a given
-       direction.  The default _limit_ method in the base class computes the
-       limit using maxima.  So for each function for which you want better
-       speed or a different behavior from maxima, you just fill in the _limit_ method.
-
-Exactly the steps above would also work for symbolic differentiation.
-(Integration is a completely different story.)
-
-Ondrej doesn't this will work (I totally disagree):
-
-"I don't think that would work for limits (it should work for
-differentiation though) except some simple cases. As an example, let's
-take this limit, that Maxima cannot do:
-
-limit((5**x+3**x)**(1/x), x, infty)
-
-(if you type this in SymPy, you will get 5, because we use the Gruntz
-algorithm, as described here:
-http://sympy.googlecode.com/svn/trunk/doc/gruntz.pdf). The only thing
-that occurs to me how to fix maxima is to match the expression and
-return 5 immediatelly, or implement the whole algorithm from scratch,
-but then you will just write the same code as we did for SymPy.
-
-Integration is quite easy - just match the expression and return a
-table integral. The general Risch algorithm is difficult, but I think
-Axiom can do it."
Index: age/calculus/predefined.py
===================================================================
--- sage/calculus/predefined.py	(revision 4062)
+++ 	(revision )
@@ -1,53 +1,0 @@
-from calculus import var
-
-a = var('a')
-b = var('b')
-c = var('c')
-d = var('d')
-f = var('f')
-g = var('g')
-h = var('h')
-i = var('i')
-j = var('j')
-k = var('k')
-l = var('l')
-m = var('m')
-n = var('n')
-o = var('o')
-p = var('p')
-q = var('q')
-r = var('r')
-s = var('s')
-t = var('t')
-u = var('u')
-v = var('v')
-w = var('w')
-x = var('x')
-y = var('y')
-z = var('z')
-A = var('A')
-B = var('B')
-C = var('C')
-D = var('D')
-E = var('E')
-F = var('F')
-G = var('G')
-H = var('H')
-J = var('J')
-K = var('K')
-L = var('L')
-M = var('M')
-N = var('N')
-O = var('O')
-P = var('P')
-Q = var('Q')
-R = var('R')
-S = var('S')
-T = var('T')
-U = var('U')
-V = var('V')
-W = var('W')
-X = var('X')
-Y = var('Y')
-Z = var('Z')
-
Index: age/calculus/tests.py
===================================================================
--- sage/calculus/tests.py	(revision 4061)
+++ 	(revision )
@@ -1,57 +1,0 @@
-"""
-TESTS
-Compute the Christoffel symbol.
-
-    sage: var('r theta phi')
-    (r, theta, phi)
-    sage: m = matrix(SR, [[(1-1/r),0,0,0],[0,-(1-1/r)^(-1),0,0],[0,0,-r^2,0],[0,0,0,-r^2*(sin(theta))^2]])
-    sage: print m
-    [        1 - (1/r)                 0                 0                 0]
-    [                0    -1/(1 - (1/r))                 0                 0]
-    [                0                 0              -r^2                 0]
-    [                0                 0                 0 -r^2*sin(theta)^2]    
-
-    sage: def christoffel(i,j,k,vars,g):
-    ...   s = 0
-    ...   ginv = g^(-1)
-    ...   for l in range(g.nrows()):
-    ...      s = s + (1/2)*ginv[k,l]*(g[j,l].diff(vars[i])+g[i,l].diff(vars[j])-g[i,j].diff(vars[l]))
-    ...   return s
-
-    sage: christoffel(3,3,2, [t,r,theta,phi], m)
-    -cos(theta)*sin(theta)
-    sage: X = christoffel(1,1,1,[t,r,theta,phi],m)
-    sage: print X
-                                     1
-                                     - - 1
-                                     r
-                                 -------------
-                                        1 2  2
-                                 2 (1 - -)  r
-                                        r    
-    sage: print X.rational_simplify()
-                                       1
-                                 - ----------
-                                      2
-                                   2 r  - 2 r    
-
-Some basic things:
-
-    sage: f(x,y) = x^3 + sinh(1/y)                   
-    sage: f
-    (x, y) |--> sinh(1/y) + x^3
-    sage: f^3
-    (x, y) |--> (sinh(1/y) + x^3)^3
-    sage: (f^3).expand()
-    (x, y) |--> sinh(1/y)^3 + 3*x^3*sinh(1/y)^2 + 3*x^6*sinh(1/y) + x^9
-
-A polynomial over a symbolic base ring:
-    sage: R = SR[x]
-    sage: f = R([1/sqrt(2), 1/(4*sqrt(2))])
-    sage: f
-    1/(4*sqrt(2))*x + 1/sqrt(2)
-    sage: -f
-    (-1/(4*sqrt(2)))*x + -1/sqrt(2)
-    sage: (-f).degree()
-    1
-"""
Index: age/calculus/var.pyx
===================================================================
--- sage/calculus/var.pyx	(revision 4059)
+++ 	(revision )
@@ -1,111 +1,0 @@
-import calculus
-
-def var(s):
-    """
-    Create a symbolic variable with the name \emph{s}.
-
-    INPUT:
-        s -- a string, either a single variable name,
-             or a space or comma separated list of
-             variable names.
-
-    NOTE: The new variable is both returned and automatically injected
-    into the global namespace.  If you use var in library code, it is
-    better to use sage.calculus.calculus.var, since it won't touch the
-    global namespace.
-
-    EXAMPLES:
-    We define three variables:
-        sage: var('xx yy zz')
-        (xx, yy, zz)
-
-    Then we make an algebraic expression out of them.
-        sage: f = xx^n + yy^n + zz^n; f
-        zz^n + yy^n + xx^n
-
-    We can substitute a new variable name for n.
-        sage: f(n = var('sigma'))
-        zz^sigma + yy^sigma + xx^sigma
-
-    If you make an important builtin variable into a symbolic variable,
-    you can get back the original value using restore:
-        sage: var('QQ RR')
-        (QQ, RR)
-        sage: QQ
-        QQ
-        sage: restore('QQ')
-        sage: QQ
-        Rational Field
-
-    We make two new variables separated by commas:
-        sage: var('theta, gamma')
-        (theta, gamma)
-        sage: theta^2 + gamma^3
-        gamma^3 + theta^2
-
-    The new variables are of type SymbolicVariable, and belong
-    to the symbolic expression ring:
-        sage: type(theta)
-        <class 'sage.calculus.calculus.SymbolicVariable'>
-        sage: parent(theta)
-        Symbolic Ring
-    """
-    G = globals()  # this is the reason the code must be in SageX.
-    v = calculus.var(s)
-    if isinstance(v, tuple):
-        for x in v:
-            G[repr(x)] = x
-    else:
-        G[repr(v)] = v
-    return v
-
-def function(s, *args):
-    """
-    Create a formal symbolic function with the name \emph{s}.
-
-    INPUT:
-        s -- a string, either a single variable name,
-             or a space or comma separated list of
-             variable names.
-
-    NOTE: The new function is both returned and automatically injected
-    into the global namespace.  If you use var in library code, it is
-    better to use sage.calculus.calculus.function, since it won't
-    touch the global namespace.
-
-    EXAMPLES:
-    We create a formal function called supersin.
-        sage: f = function('supersin', x)
-        sage: f
-        supersin(x)
-
-    We can immediately use supersin in symbolic expressions:
-        sage: supersin(y+z) + A^3
-        A^3 + supersin(z + y)
-
-    We can define other functions in terms of supersin.
-        sage: g(x,y) = supersin(x)^2 + sin(y/2)
-        sage: g
-        (x, y) |--> sin(y/2) + supersin(x)^2
-        sage: g.diff(y)
-        (x, y) |--> cos(y/2)/2
-        sage: g.diff(x)
-        (x, y) |--> 2*supersin(x)*diff(supersin(x), x, 1)
-        sage: k = g.diff(x); k
-        (x, y) |--> 2*supersin(x)*diff(supersin(x), x, 1)
-        sage: k.substitute(supersin=sin)
-        2*sin(x)*diff(supersin(x), x, 1)
-    """
-    if len(args) > 0:
-        return function(s)(*args)
-    
-    G = globals()  # this is the reason the code must be in SageX.
-    v = calculus.function(s)
-    if isinstance(v, tuple):
-        for x in v:
-            G[repr(x)] = x
-    else:
-        G[repr(v)] = v
-    return v
-
-
Index: age/calculus/wester.py
===================================================================
--- sage/calculus/wester.py	(revision 4058)
+++ 	(revision )
@@ -1,538 +1,0 @@
-"""
-These are all the problems at 
-    http://yacas.sourceforge.net/essaysmanual.html
-
-They come from the 1994 paper "Review of CAS mathematical capabilities",
-by Michael Wester, who put forward 123 problems that a reasonable computer
-algebra system should be able to solve and tested the then current
-versions of various commercial CAS on this list.   SAGE can do most of
-the problems natively now, i.e., with no explicit calls to maxima or
-other systems. 
-
-
-sage: factorial(50)
-30414093201713378043612608166064768844377641568960512000000000000
-sage: factor(factorial(50))
-2^47 * 3^22 * 5^12 * 7^8 * 11^4 * 13^3 * 17^2 * 19^2 * 23^2 * 29 * 31 * 37 * 41 * 43 * 47
-
-sage: # 1/2+...+1/10 = 4861/2520
-sage: sum(1/n for n in range(2,10+1)) == 4861/2520
-True
-
-sage: # Evaluate  e^(Pi*Sqrt(163)) to 50 decimal digits
-sage: a = e^(pi*sqrt(163)); a
-e^(sqrt(163)*pi)
-sage: print RealField(150)(a)
-262537412640768743.99999999999925007259719819
-
-sage: # Evaluate the Bessel function J[2] numerically at z=1+I.
-sage: # NOTE -- we get a different answer than yacas
-sage: bessel_J(2.0,1.0+I)
-0.874211097673326 - 0.222469792478650*I
-
-sage: # Obtain period of decimal fraction 1/7=0.(142857).
-sage: a = 1/7
-sage: print a
-1/7
-sage: print a.period()
-6
-
-sage: # Continued fraction of 3.1415926535
-sage: a = 3.1415926535
-sage: continued_fraction(a)
-[3, 7, 15, 1, 292, 1, 1, 6, 2, 13, 4]
-
-sage: # (not exactly ok) Sqrt(2*Sqrt(3)+4)=1+Sqrt(3).
-sage: # The maxima backend equality checker fails this; maybe it *should*, since
-sage: # the equality only holds for one choice of sign.
-sage: a = sqrt(2*sqrt(3) + 4); b = 1 + sqrt(3)
-sage: print float(a-b)
-0.0
-sage: print bool(a == b)
-False
-sage: # We can, of course, do this in a quadratic field
-sage: k.<sqrt3> = QuadraticField(3)
-sage: asqr = 2*sqrt3 + 4
-sage: b = 1+sqrt3
-sage: asqr == b^2
-True
-
-sage: # (not exactly ok) Sqrt(14+3*Sqrt(3+2*Sqrt(5-12*Sqrt(3-2*Sqrt(2)))))=3+Sqrt(2).
-sage: a = sqrt(14+3*sqrt(3+2*sqrt(5-12*sqrt(3-2*sqrt(2)))))
-sage: b = 3+sqrt(2)
-sage: print a, b
-sqrt(3 sqrt(2 sqrt(5 - 12 sqrt(3 - 2 sqrt(2))) + 3) + 14)                                  sqrt(2) + 3
-sage: print bool(a==b)
-False
-sage: print float(a-b)
-1.7763568394e-15
-sage: # 2*Infinity-3=Infinity.
-sage: 2*infinity-3 == infinity
-True
-
-sage: # (YES) Standard deviation of the sample (1, 2, 3, 4, 5).
-sage: v = vector(RDF, 5, [1,2,3,4,5])
-sage: v.standard_deviation()
-1.5811388300841898
-
-sage: # (NO) Hypothesis testing with t-distribution.
-sage: # (NO) Hypothesis testing with chi^2 distribution
-
-sage: # (YES) (x^2-4)/(x^2+4*x+4)=(x-2)/(x+2).
-sage: R.<x> = QQ[]
-sage: (x^2-4)/(x^2+4*x+4) == (x-2)/(x+2)
-True
-sage: restore('x')
-
-sage: # (NO -- Maxima doesn't consider them equal.) 
-sage: # (Exp(x)-1)/(Exp(x/2)+1)=Exp(x/2)-1.
-sage: f = (exp(x)-1)/(exp(x/2)+1)
-sage: g = exp(x/2)-1
-sage: f
-(e^x - 1)/(e^(x/2) + 1)
-sage: g
-e^(x/2) - 1
-sage: print f(10.0), g(10.0)
-147.4131591025766 147.4131591025766
-sage: print bool(f == g)
-False
-
-sage: # (YES) Expand (1+x)^20, take derivative and factorize.
-sage: # first do it is using algebraic polys
-sage: R.<x> = QQ[]
-sage: f = (1+x)^20
-sage: print f
-x^20 + 20*x^19 + 190*x^18 + 1140*x^17 + 4845*x^16 + 15504*x^15 + 38760*x^14 + 77520*x^13 + 125970*x^12 + 167960*x^11 + 184756*x^10 + 167960*x^9 + 125970*x^8 + 77520*x^7 + 38760*x^6 + 15504*x^5 + 4845*x^4 + 1140*x^3 + 190*x^2 + 20*x + 1
-sage: print f.factor()
-(x + 1)^20
-sage: # next do it symbolically
-sage: restore('x')
-sage: f = (1+x)^20; f
-(x + 1)^20
-sage: g = f.expand(); g
-x^20 + 20*x^19 + 190*x^18 + 1140*x^17 + 4845*x^16 + 15504*x^15 + 38760*x^14 + 77520*x^13 + 125970*x^12 + 167960*x^11 + 184756*x^10 + 167960*x^9 + 125970*x^8 + 77520*x^7 + 38760*x^6 + 15504*x^5 + 4845*x^4 + 1140*x^3 + 190*x^2 + 20*x + 1
-sage: g.factor()
-(x + 1)^20
-
-
-sage: # (YES) Factorize x^100-1.
-sage: factor(x^100-1)
-(x - 1)*(x + 1)*(x^2 + 1)*(x^4 - x^3 + x^2 - x + 1)*(x^4 + x^3 + x^2 + x + 1)*(x^8 - x^6 + x^4 - x^2 + 1)*(x^20 - x^15 + x^10 - x^5 + 1)*(x^20 + x^15 + x^10 + x^5 + 1)*(x^40 - x^30 + x^20 - x^10 + 1)
-sage: # Also, algebraically
-sage: x = polygen(QQ)
-sage: factor(x^100 - 1)
-(x - 1) * (x + 1) * (x^2 + 1) * (x^4 - x^3 + x^2 - x + 1) * (x^4 + x^3 + x^2 + x + 1) * (x^8 - x^6 + x^4 - x^2 + 1) * (x^20 - x^15 + x^10 - x^5 + 1) * (x^20 + x^15 + x^10 + x^5 + 1) * (x^40 - x^30 + x^20 - x^10 + 1)
-sage: restore('x')
-
-
-sage: # (YES) Factorize  x^4-3*x^2+1 in the field of rational numbers extended by roots of  x^2-x-1.
-sage: k.< a> = NumberField(x^2 - x -1)
-sage: R.< y> = k[]
-sage: f = y^4 - 3*y^2 + 1
-sage: f
-y^4 + (-3)*y^2 + 1
-sage: factor(f)
-(y + -a) * (y + -a + 1) * (y + a - 1) * (y + a)
-
-sage: # (YES) Factorize  x^4-3*x^2+1 mod 5.
-sage: k.< x > = GF(5) [ ]
-sage: f = x^4 - 3*x^2 + 1
-sage: f.factor()
-(x + 2)^2 * (x + 3)^2
-sage: # Alternatively, from symbol x as follows:
-sage: reset('x')
-sage: f = x^4 - 3*x^2 + 1
-sage: f.polynomial(GF(5)).factor()
-(x + 2)^2 * (x + 3)^2
-
-sage: # (YES) Partial fraction decomposition of (x^2+2*x+3)/(x^3+4*x^2+5*x+2)
-sage: f = (x^2+2*x+3)/(x^3+4*x^2+5*x+2)
-sage: print f
-                                  2
-                                 x  + 2 x + 3
-                              -------------------
-                               3      2
-                              x  + 4 x  + 5 x + 2
-
-sage: print f.partial_fraction()
-                             3	     2	      2
-                           ----- - ----- + --------
-                           x + 2   x + 1	  2
-                                           (x + 1)
-
-                                           
-sage: # (BUG?) Assuming  x>=y,  y>=z,  z>=x, deduce  x=z.
-sage: # Maxima doesn't agree that x==z is a conclusion...
-sage: forget()
-sage: restore('x,y,z')
-sage: assume(x>=y, y>=z,z>=x)
-sage: print bool(x==z)
-False
-
-sage: # (YES) Assuming x>y, y>0, deduce 2*x^2>2*y^2.
-sage: forget()
-sage: assume(x>y, y>0)
-sage: print assumptions()
-[x > y, y > 0]
-sage: print bool(2*x^2 > 2*y^2)
-True
-sage: forget()
-sage: print assumptions()
-[]
-sage: # Solve the inequality Abs(x-1)>2.
-
-sage: # (NO) Maxima doesn't solve inequalities:
-sage: eqn = abs(x-1) > 2
-sage: print eqn
-                                abs(x - 1) > 2
-
-sage: # (NO) Solve the inequality (x-1)*...*(x-5)<0.
-sage: eqn = prod(x-i for i in range(1,5 +1)) < 0
-sage: # but don't know how to solve
-sage: print eqn
-                  (x - 5) (x - 4) (x - 3) (x - 2) (x - 1) < 0
-
-
-sage: # (YES) Cos(3*x)/Cos(x)=Cos(x)^2-3*Sin(x)^2 or similar equivalent combination.
-sage: f = cos(3*x)/cos(x)
-sage: g = cos(x)^2 - 3*sin(x)^2
-sage: h = f-g
-sage: print h.trig_simplify()
-                                       0
-
-sage: # (YES) Cos(3*x)/Cos(x)=2*Cos(2*x)-1.
-sage: f = cos(3*x)/cos(x)
-sage: g = 2*cos(2*x) - 1
-sage: h = f-g
-sage: print h.trig_simplify()
-                                       0
-sage: # (NO) Define rewrite rules to match  Cos(3*x)/Cos(x)=Cos(x)^2-3*Sin(x)^2.
-sage: # SAGE has no notion of "rewrite rules". 
-
-
-sage: # (YES) Sqrt(997)-(997^3)^(1/6)=0
-sage: a = sqrt(997) - (997^3)^(1/6)
-sage: print a
-                                       0
-sage: print bool(a == 0)
-True
-
-sage: # (NO) Sqrt(99983)-99983^3^(1/6)=0
-sage: # For some reason Maxima decides its not zero because of the factorization. 
-sage: a = sqrt(99983) - (99983^3)^(1/6)
-sage: print a
-                       sqrt(99983) - sqrt(13) sqrt(7691)
-sage: print bool(a==0)
-False
-sage: print float(a)
-1.13686837722e-13
-sage: print 13*7691
-99983
-
-sage: # (YES) (2^(1/3) + 4^(1/3))^3 - 6*(2^(1/3) + 4^(1/3))-6 = 0
-sage: ## same issue as above -- can only do using number fields
-sage: a = (2^(1/3) + 4^(1/3))^3 - 6*(2^(1/3) + 4^(1/3)) - 6
-sage: print a
-		       1/3    1/3 3	  1/3	 1/3
-        	     (4	   + 2	 )  - 6 (4    + 2   ) - 6
-sage: print bool(a==0)
-False
-sage: print float(a)
-3.5527136788e-15
-sage: ## but we can do it using number fields.
-sage: reset('x')
-sage: k.<b> = NumberField(x^3-2)
-sage: a = (b  + b^2)^3 - 6*(b  + b^2) - 6
-sage: print a
-0
-
-sage: # (YES) Ln(Tan(x/2+Pi/4))-ArcSinh(Tan(x))=0
-sage: # Yes, in that the thing is clearly not equal to 0!
-sage: f = log(tan(x/2 + pi/4)) - asin(tan(x))
-sage: bool(f == 0)
-False
-sage: [float(f(i/10)) for i in range(1,5)]           # random low order bits
-[-0.00033670040754082975, -0.0027778004096620235, -0.0098909940914040928, -0.025411145508414501]
-
-sage: # (YES) Numerically, the expression Ln(Tan(x/2+Pi/4))-ArcSinh(Tan(x))=0 and its derivative at x=0 are zero.
-sage: g = f.derivative()
-sage: print float(f(0))
--1.11022302463e-16
-sage: print float(g(0))
--1.11022302463e-16
-sage: print g
-                         2 x    pi
-                      sec (- + ---)            2
-                           2    4           sec (x)
-                      -------------- - -----------------
-                            x    pi                2
-                      2 tan(- + ---)   sqrt(1 - tan (x))
-                            2    4
-                            
-
-sage: # (NO?) Ln((2*Sqrt(r) + 1)/Sqrt(4*r 4*Sqrt(r) 1))=0.
-sage: f = log( (2*sqrt(r) + 1) / sqrt(4*r  + 4*sqrt(r) +  1))
-sage: print f
-                                  2 sqrt(r) + 1
-                        log(-------------------------)
-                            sqrt(4 r + 4 sqrt(r) + 1)
-sage: print bool(f == 0)
-False
-sage: print [float(f(i)) for i in [0.1,0.3,0.5]]
-[0.0, 0.0, 0.0]
-
-
-sage: # (NO, except numerically)
-sage: # (4*r+4*Sqrt(r)+1)^(Sqrt(r)/(2*Sqrt(r)+1))*(2*Sqrt(r)+1)^(2*Sqrt(r)+1)^(-1)-2*Sqrt(r)-1=0, assuming r>0.
-sage: assume(r>0)
-sage: f = (4*r+4*sqrt(r)+1)^(sqrt(r)/(2*sqrt(r)+1))*(2*sqrt(r)+1)^(2*sqrt(r)+1)^(-1)-2*sqrt(r)-1
-sage: print f
-                             1				     sqrt(r)
-                       -------------			  -------------
-                       2 sqrt(r) + 1			  2 sqrt(r) + 1
-        (2 sqrt(r) + 1)		     (4 r + 4 sqrt(r) + 1)
-                                                                - 2 sqrt(r) - 1
-sage: print bool(f == 0)
-False
-sage: print [float(f(i)) for i in [0.1,0.3,0.5]]
-[0.0, 0.0, -2.2204460492503131e-16]
-
-
-sage: # (YES) Obtain real and imaginary parts of Ln(3+4*I).
-sage: a = log(3+4*I)
-sage: print a
-                                 log(4  I + 3)
-sage: print a.real()
-                                    log(5)
-sage: print a.imag()
-                                         4
-                                    atan(-)
-                                         3
-
-sage: # (YES) Obtain real and imaginary parts of Tan(x+I*y)
-sage: a = tan(x + I*y)
-sage: print a
-                                 tan( I y + x)
-sage: print a.real()
-                                   sin(2 x)
-                             --------------------
-                             cosh(2 y) + cos(2 x)
-sage: print a.imag()
-                                  sinh(2 y)
-                             --------------------
-                             cosh(2 y) + cos(2 x)
-
-sage: # (YES) Simplify Ln(Exp(z)) to z for -Pi<Im(z)<=Pi.
-sage: f = log(exp(z))
-sage: # (except it does it even without the constraint)
-sage: assume(-pi < imag(z))
-sage: assume(imag(z) <= pi)
-sage: f
-z
-sage: forget()
-
-sage: # (YES) Assuming Re(x)>0, Re(y)>0, deduce x^(1/n)*y^(1/n)-(x*y)^(1/n)=0.
-sage: assume(real(x) > 0, real(y) > 0)
-sage: f = x^(1/n)*y^(1/n)-(x*y)^(1/n)
-sage: print f
-                                       0
-sage: forget()
-
-sage: # (??) Transform equations, (x==2)/2+(1==1)=>x/2+1==2.
-sage: # This doesn't make any sense, in my opinion.  Adding equations
-
-sage: # (SOMEWHAT) Solve Exp(x)=1 and get all solutions.
-sage: solve(exp(x) == 1)
-[x == 0]
-
-sage: # (SOMEWHAT) Solve Tan(x)=1 and get all solutions.
-sage: solve(tan(x) == 1)
-[x == (pi/4)]
-
-sage: # (YES) Solve a degenerate 3x3 linear system.
-sage: # x+y+z==6,2*x+y+2*z==10,x+3*y+z==10
-sage: # First symbolically:
-sage: solve([x+y+z==6, 2*x+y+2*z==10, x+3*y+z==10], x,y,z)   
-[[x == (4 - r1), y == 2, z == r1]]
-
-sage: # (YES) Invert a 2x2 symbolic matrix.
-sage: # [[a,b],[1,a*b]]
-sage: # Using multivariate poly ring -- much nicer
-sage: R.<a,b> = QQ[]
-sage: m = matrix(2,2,[a,b,  1, a*b])
-sage: zz = m^(-1)
-sage: print zz
-[       a/(-1 + a^2)     (-1)/(-1 + a^2)]
-[(-1)/(-1*b + a^2*b)    a/(-1*b + a^2*b)]
-
-sage: # (YES) Compute and factor the determinant of the 4x4 Vandermonde matrix in a, b, c, d.
-sage: restore('a,b,c,d')
-sage: m = matrix(SR, 4, 4, [[z^i for i in range(4)] for z in [a,b,c,d]])
-sage: print m
-    [  1   a a^2 a^3]
-    [  1   b b^2 b^3]
-    [  1   c c^2 c^3]
-    [  1   d d^2 d^3]
-sage: d = m.determinant()
-sage: print d.factor()
-                (b - a) (c - a) (c - b) (d - a) (d - b) (d - c)
-                
-sage: # (YES) Compute and factor the determinant of the 4x4 Vandermonde matrix in a, b, c, d.
-sage: # Do it instead in a multivariate ring
-sage: R.<a,b,c,d> = QQ[]
-sage: m = matrix(R, 4, 4, [[z^i for i in range(4)] for z in [a,b,c,d]])
-sage: print m
-[  1   a a^2 a^3]
-[  1   b b^2 b^3]
-[  1   c c^2 c^3]
-[  1   d d^2 d^3]
-sage: d = m.determinant()
-sage: print d
-b*c^2*d^3 - b*c^3*d^2 - b^2*c*d^3 + b^2*c^3*d + b^3*c*d^2 - b^3*c^2*d - a*c^2*d^3 + a*c^3*d^2 + a*b^2*d^3 - a*b^2*c^3 - a*b^3*d^2 + a*b^3*c^2 + a^2*c*d^3 - a^2*c^3*d - a^2*b*d^3 + a^2*b*c^3 + a^2*b^3*d - a^2*b^3*c - a^3*c*d^2 + a^3*c^2*d + a^3*b*d^2 - a^3*b*c^2 - a^3*b^2*d + a^3*b^2*c
-sage: print d.factor()
-(-1) * (-1*d + c) * (-1*d + b) * (-1*c + b) * (b - a) * (-1*d + a) * (-1*c + a)
-
-sage: # Find the eigenvalues of a 3x3 integer matrix.
-sage: m = matrix(QQ, 3, [5,-3,-7, -2,1,2, 2,-3,-4])
-sage: m.eigenspaces()
-[
-(3, [
-(1, 0, -1)
-]),
-(1, [
-(1, 1, -1)
-]),
-(-2, [
-(0, 1, 1)
-])
-]
-
-sage: # OK Verify some standard limits found by L'Hopital's rule:
-sage: #   Verify(Limit(x,Infinity) (1+1/x)^x, Exp(1));
-sage: #   Verify(Limit(x,0) (1-Cos(x))/x^2, 1/2);
-sage: print limit( (1+1/x)^x, x = oo)
-e
-sage: print limit( (1-cos(x))/(x^2), x = 1/2)
-                                           1
-                                 4 - 4 cos(-)
-                                           2
-
-sage: # (OK-ish) D(x)Abs(x)
-sage: #    Verify(D(x) Abs(x), Sign(x));
-sage: diff(abs(x))
-x/abs(x)
-
-sage: # (NO) (Integrate(x)Abs(x))=Abs(x)*x/2
-sage: integral(abs(x), x)
-integrate(abs(x), x)
-
-sage: #  (YES) Compute derivative of Abs(x), piecewise defined.
-sage: #     Verify(D(x)if(x<0) (-x) else x,
-sage: #        Simplify(if(x<0) -1 else 1))
-Piecewise defined function with 2 parts, [[(-10, 0), -1], [(0, 10), 1]]
-sage: #  (NOT really) Integrate Abs(x), piecewise defined.
-sage: #      Verify(Simplify(Integrate(x)
-sage: #        if(x<0) (-x) else x),
-sage: #        Simplify(if(x<0) (-x^2/2) else x^2/2));
-sage: f = piecewise([ [[-10,0], -x], [[0,10], x]])
-sage: f.integral()
-100
-
-sage: # (YES) Taylor series of 1/Sqrt(1-v^2/c^2) at v=0.
-sage: restore('v,c')
-sage: taylor(1/sqrt(1-v^2/c^2), v, 0, 7)
-1 + v^2/(2*c^2) + 3*v^4/(8*c^4) + 5*v^6/(16*c^6)
-
-sage: # (OK-ish) (Taylor expansion of Sin(x))/(Taylor expansion of Cos(x)) = (Taylor expansion of Tan(x)).
-sage: #      TestYacas(Taylor(x,0,5)(Taylor(x,0,5)Sin(x))/
-sage: #        (Taylor(x,0,5)Cos(x)), Taylor(x,0,5)Tan(x));
-sage: f = taylor(sin(x), x, 0, 8)
-sage: g = taylor(cos(x), x, 0, 8)
-sage: h = taylor(tan(x), x, 0, 8)
-sage: f = f.power_series(QQ)
-sage: g = g.power_series(QQ)
-sage: h = h.power_series(QQ)
-sage: f - g*h
-O(x^8)
-
-sage: # (YES) Taylor expansion of Ln(x)^a*Exp(-b*x) at x=1.
-sage: taylor(log(x)^a * exp(-b*x), x, 1, 3)
-(x - 1)^a/e^b - (((x - 1)^a*a + 2*b*(x - 1)^a)*(x - 1)/(2*e^b)) + (3*(x - 1)^a*a^2 + (12*b + 5)*(x - 1)^a*a + 12*b^2*(x - 1)^a)*(x - 1)^2/(24*e^b) - (((x - 1)^a*a^3 + (6*b + 5)*(x - 1)^a*a^2 + (12*b^2 + 10*b + 6)*(x - 1)^a*a + 8*b^3*(x - 1)^a)*(x - 1)^3/(48*e^b))
-
-sage: # (YES) Taylor expansion of Ln(Sin(x)/x) at x=0.
-sage: taylor(log(sin(x)/x), x, 0, 10)
--x^2/6 - (x^4/180) - (x^6/2835) - (x^8/37800) - (x^10/467775)
-
-sage: # (NO) Compute n-th term of the Taylor series of Ln(Sin(x)/x) at x=0.
-sage: # need formal functions
-
-sage: # (NO) Compute n-th term of the Taylor series of Exp(-x)*Sin(x) at x=0.
-sage: # (Sort of, with some work)
-sage: # Solve x=Sin(y)+Cos(y) for y as Taylor series in x at x=1.
-sage: #      TestYacas(InverseTaylor(y,0,4) Sin(y)+Cos(y),
-sage: #        (y-1)+(y-1)^2/2+2*(y-1)^3/3+(y-1)^4);
-sage: #       Note that InverseTaylor does not give the series in terms of x but in terms of y which is semantically 
-sage: # wrong. But other CAS do the same.
-sage: f = sin(y) + cos(y)
-sage: g = f.taylor(y, 0, 10)
-sage: h = g.power_series(QQ)
-sage: k = (h - 1).reversion()
-sage: print k
-y + 1/2*y^2 + 2/3*y^3 + y^4 + 17/10*y^5 + 37/12*y^6 + 41/7*y^7 + 23/2*y^8 + 1667/72*y^9 + 3803/80*y^10 + O(y^11)
-
-sage: # [OK] Compute Legendre polynomials directly from Rodrigues's formula, P[n]=1/(2^n*n!) *(Deriv(x,n)(x^2-1)^n).
-sage: #      P(n,x) := Simplify( 1/(2*n)!! *
-sage: #        Deriv(x,n) (x^2-1)^n );
-sage: #      TestYacas(P(4,x), (35*x^4)/8+(-15*x^2)/4+3/8);
-sage: def P(n,x):
-...    return   simplify(diff((x^2-1)^n,x,n) / (2^n * factorial(n)))
-...
-sage: print P(4,x).expand()
-                                   4	   2
-                               35 x    15 x    3
-                               ----- - ----- + -
-                                 8	 4     8
-
-sage: # (YES) Define the polynomial p=Sum(i,1,5,a[i]*x^i).
-sage: # symbolically
-sage: ps = sum(var('a%s'%i)*x^i for i in range(1,6))
-sage: print 'symbolic\n',ps
-symbolic
-                         5	 4	 3	 2
-                     a5 x  + a4 x  + a3 x  + a2 x  + a1 x
-sage: # algebraically
-sage: R = PolynomialRing(QQ,5,names='a')
-sage: S.<x> = PolynomialRing(R)
-sage: p = S(list(R.gens()))*x
-sage: print 'algebraic\n',p
-algebraic
-a4*x^5 + a3*x^4 + a2*x^3 + a1*x^2 + a0*x
-
-sage: # (YES) Convert the above to Horner's form.
-sage: #      Verify(Horner(p, x), ((((a[5]*x+a[4])*x
-sage: #        +a[3])*x+a[2])*x+a[1])*x);
-sage: # We use the trick of evaluating the algebraic poly at a symbolic variable:
-sage: restore('x')
-sage: p(x)
-x*(x*(x*(x*(a4*x + a3) + a2) + a1) + a0)
-
-sage: # (NO) Convert the result of problem 127 to Fortran syntax.
-sage: #      CForm(Horner(p, x));
-
-sage: # (YES) Verify that True And False=False.
-sage: (True and False) == False
-True
-
-sage: # (YES) Prove x Or Not x.
-sage: for x in [True, False]:
-...    print x or (not x)
-True
-True
-
-sage: # (YES) Prove x Or y Or x And y=>x Or y.
-sage: for x in [True, False]:
-...   for y in [True, False]:
-...       if x or y or x and y:
-...           if not (x or y):
-...              print "failed!"
-"""    
Index: sage/catalogue/catalogue.py
===================================================================
--- sage/catalogue/catalogue.py	(revision 3983)
+++ sage/catalogue/catalogue.py	(revision 2320)
@@ -120,6 +120,7 @@
 elementary = Elementary()
 function.elementary = elementary
-import sage.calculus.all
-elementary.sin = sage.calculus.all.sin
-elementary.cos = sage.calculus.all.cos
-elementary.log = sage.calculus.all.log
+import sage.functions.all
+elementary.sin = sage.functions.all.sin
+elementary.cos = sage.functions.all.cos
+    
+    
Index: sage/coding/all.py
===================================================================
--- sage/coding/all.py	(revision 3972)
+++ sage/coding/all.py	(revision 2132)
@@ -24,19 +24,3 @@
 from ag_code import ag_code
 
-from code_bounds import (codesize_upper_bound,
-                         dimension_upper_bound,
-                         volume_hamming,
-                         gilbert_lower_bound,
-                         plotkin_upper_bound,
-                         griesmer_upper_bound,
-                         elias_upper_bound,
-                         hamming_upper_bound,
-                         singleton_upper_bound,
-                         gv_info_rate,
-                         entropy,
-                         gv_bound_asymp,
-                         hamming_bound_asymp,
-                         singleton_bound_asymp,
-                         plotkin_bound_asymp,
-                         elias_bound_asymp,
-                         mrrw1_bound_asymp)
+from code_bounds import *
Index: sage/coding/code_bounds.py
===================================================================
--- sage/coding/code_bounds.py	(revision 4062)
+++ sage/coding/code_bounds.py	(revision 3290)
@@ -136,5 +136,5 @@
 
 from sage.interfaces.all import gap
-from sage.rings.all import QQ, RR, ZZ, RDF
+from sage.rings.all import QQ, RR, ZZ
 from sage.rings.arith import factorial
 from sage.misc.functional import log, sqrt
@@ -373,8 +373,8 @@
     EXAMPLES:
         sage: elias_bound_asymp(1/4,2)
-        0.399123963308
+        0.399123963307144
     """
     r = 1-1/q
-    return RDF((1-entropy(r-sqrt(r*(r-delta)), q)))
+    return (1-entropy(r-sqrt(r*(r-delta)), q))
 
 def mrrw1_bound_asymp(delta,q):
@@ -385,11 +385,11 @@
     EXAMPLES:
         sage: mrrw1_bound_asymp(1/4,2)
-        0.354578902665
-
-    """
-    return RDF(entropy((q-1-delta*(q-2)-2*sqrt((q-1)*delta*(1-delta)))/q,q))
-
-
-
-
-
+        0.354578902665270
+
+    """
+    return entropy((q-1-delta*(q-2)-2*sqrt((q-1)*delta*(1-delta)))/q,q)
+
+
+
+
+
Index: sage/coding/linear_code.py
===================================================================
--- sage/coding/linear_code.py	(revision 4063)
+++ sage/coding/linear_code.py	(revision 2779)
@@ -142,11 +142,4 @@
 added LinearCode_from_vectorspace, extended_code, zeta_function
     -- Nick Alexander (2006-12-10): factor GUAVA code to guava.py
-
-TESTS:
-   sage: MS = MatrixSpace(GF(2),4,7)
-   sage: G  = MS([[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]])
-   sage: C  = LinearCode(G)
-   sage: C == loads(dumps(C))
-   True
 """
 
@@ -634,7 +627,5 @@
 
     def __cmp__(self, right):
-        if not isinstance(right, LinearCode):
-            return cmp(type(self), type(right))
-        return cmp(self.__gen_mat, right.__gen_mat)
+        raise NotImplementedError
 
     def decode(self, right):
@@ -785,4 +776,5 @@
  
         EXAMPLES:
+ 
         """
         slength = self.length()
@@ -793,9 +785,9 @@
         rF = right.base_ring()
         if slength != rlength:
-            return False
+            return 0
         if sdim != rdim:
-            return False
+            return 0
         if sF != rF:
-            return False
+            return 0
         V = VectorSpace(sF,sdim)
         sbasis = self.gens()
@@ -804,10 +796,10 @@
         rcheck = right.check_mat()
         for c in sbasis:
-            if rcheck*c:
-                return False
+            if rcheck*c != V(0):
+                return 0
         for c in rbasis:
-            if scheck*c:
-                return False
-        return True
+            if scheck*c != V(0):
+                return 0
+        return 1
 
     def is_permutation_automorphism(self,g):
Index: sage/combinat/combinat.py
===================================================================
--- sage/combinat/combinat.py	(revision 4022)
+++ sage/combinat/combinat.py	(revision 2664)
@@ -16,108 +16,101 @@
 \item Bell numbers, \code{bell_number}
 
-\item Bernoulli numbers, \code{bernoulli_number} (though PARI's
-  bernoulli is better)
-
-\item Catalan numbers, \code{catalan_number} (not to be confused with
-  the Catalan constant)
+\item Bernoulli numbers, \code{bernoulli_number} (though PARI's bernoulli is 
+  better)
+
+\item Catalan numbers, \code{catalan_number} (not to be confused with the
+  Catalan constant)
 
 \item Eulerian/Euler numbers, \code{euler_number} (Maxima)
 
-\item Fibonacci numbers, \code{fibonacci} (PARI) and
-  \code{fibonacci_number} (GAP) The PARI version is better.
+\item Fibonacci numbers, \code{fibonacci} (PARI) and \code{fibonacci_number} (GAP)
+  The PARI version is better.
 
 \item Lucas numbers, \code{lucas_number1}, \code{lucas_number2}.
  
-\item Stirling numbers, \code{stirling_number1},
-\code{stirling_number2}.
-
+\item Stirling numbers, \code{stirling_number1}, \code{stirling_number2}.
 \end{itemize}
  
 Set-theoretic constructions:
 \begin{itemize}
-
-\item Combinations of a multiset, \code{combinations},
-\code{combinations_iterator}, and \code{number_of_combinations}. These
-are unordered selections without repetition of k objects from a
-multiset S.
-
-\item Arrangements of a multiset, \code{arrangements} and
-  \code{number_of_arrangements} These are ordered selections without
-  repetition of k objects from a multiset S.
-
-\item Derangements of a multiset, \code{derangements} and
-\code{number_of_derangements}.
+\item Combinations of a multiset, \code{combinations}, \code{combinations_iterator},
+and \code{number_of_combinations}. These are unordered selections without
+repetition of k objects from a multiset S.
+
+\item Arrangements of a multiset, \code{arrangements} and \code{number_of_arrangements}
+  These are ordered selections without repetition of k objects from a 
+  multiset S.
+
+\item Derangements of a multiset, \code{derangements} and \code{number_of_derangements}.
 
 \item Tuples of a multiset, \code{tuples} and \code{number_of_tuples}.
-  An ordered tuple of length k of set S is a ordered selection with
-  repetitions of S and is represented by a sorted list of length k
-  containing elements from S.
-
-\item Unordered tuples of a set, \code{unordered_tuple} and
-  \code{number_of_unordered_tuples}.  An unordered tuple of length k
-  of set S is a unordered selection with repetitions of S and is
-  represented by a sorted list of length k containing elements from S.
-
-\item Permutations of a multiset, \code{permutations},
-\code{permutations_iterator}, \code{number_of_permutations}. A
-permutation is a list that contains exactly the same elements but
+  An ordered tuple of length k of set S is a ordered selection with 
+  repetitions of S and is represented by a sorted list of length k 
+  containing elements from S. 
+
+\item Unordered tuples of a set, \code{unordered_tuple} and \code{number_of_unordered_tuples}.
+  An unordered tuple of length k of set S is a unordered selection with 
+  repetitions of S and is represented by a sorted list of length k 
+  containing elements from S. 
+
+\item Permutations of a multiset, \code{permutations}, \code{permutations_iterator},
+\code{number_of_permutations}. A permutation is a list that contains exactly the same elements but 
 possibly in different order.
-
 \end{itemize}
 
 Partitions:
 \begin{itemize}
-
-\item Partitions of a set, \code{partitions_set},
-  \code{number_of_partitions_set}.  An unordered partition of set S is
-  a set of pairwise disjoint nonempty sets with union S and is
-  represented by a sorted list of such sets.
-
-\item Partitions of an integer, \code{partitions_list},
-  \code{number_of_partitions_list}.  An unordered partition of n is an
-  unordered sum $n = p_1+p_2 +\ldots+ p_k$ of positive integers and is
-  represented by the list $p = [p_1,p_2,\ldots,p_k]$, in nonincreasing
-  order, i.e., $p1\geq p_2 ...\geq p_k$.
-
-\item Ordered partitions of an integer, \code{ordered_partitions},
-  \code{number_of_ordered_partitions}.  An ordered partition of n is
-  an ordered sum $n = p_1+p_2 +\ldots+ p_k$ of positive integers and
-  is represented by the list $p = [p_1,p_2,\ldots,p_k]$, in
-  nonincreasing order, i.e., $p1\geq p_2 ...\geq p_k$.
-
-\item Restricted partitions of an integer,
-  \code{partitions_restricted},
-  \code{number_of_partitions_restricted}.  An unordered restricted
-  partition of n is an unordered sum $n = p_1+p_2 +\ldots+ p_k$ of
-  positive integers $p_i$ belonging to a given set $S$, and is
-  represented by the list $p = [p_1,p_2,\ldots,p_k]$, in nonincreasing
-  order, i.e., $p1\geq p_2 ...\geq p_k$.
-
-\item \code{partitions_greatest} implements a special type of
-   restricted partition.
-
-\item \code{partitions_greatest_eq} is another type of restricted
-partition.
+\item Partitions of a set, \code{partitions_set}, \code{number_of_partitions_set}.
+  An unordered partition of set S is a set of pairwise disjoint 
+  nonempty sets with union S and is represented by a sorted list of 
+  such sets. 
+
+\item Partitions of an integer, \code{partitions_list}, \code{number_of_partitions_list}.
+  An unordered partition of n is an unordered sum 
+  $n = p_1+p_2 +\ldots+ p_k$ of positive integers and is represented by 
+  the list $p = [p_1,p_2,\ldots,p_k]$, in nonincreasing order, i.e., 
+  $p1\geq p_2 ...\geq p_k$. 
+
+\item Ordered partitions of an integer, \code{ordered_partitions}, 
+  \code{number_of_ordered_partitions}.
+  An ordered partition of n is an ordered sum $n = p_1+p_2 +\ldots+ p_k$ 
+  of positive integers and is represented by 
+  the list $p = [p_1,p_2,\ldots,p_k]$, in nonincreasing order, i.e., 
+  $p1\geq p_2 ...\geq p_k$. 
+
+\item Restricted partitions of an integer, \code{partitions_restricted}, 
+  \code{number_of_partitions_restricted}.
+  An unordered restricted partition of n is an unordered sum 
+  $n = p_1+p_2 +\ldots+ p_k$ of positive integers $p_i$ belonging to a
+  given set $S$, and is represented by the list $p = [p_1,p_2,\ldots,p_k]$, 
+  in nonincreasing order, i.e., $p1\geq p_2 ...\geq p_k$. 
+
+\item \code{partitions_greatest}
+   implements a special type of restricted partition.
+
+\item \code{partitions_greatest_eq} is another type of restricted partition.
 
 \item Tuples of partitions, \code{partition_tuples},
-  \code{number_of_partition_tuples}.  A $k$-tuple of partitions is
-  represented by a list of all $k$-tuples of partitions which together
-  form a partition of $n$.
-
-\item Powers of a partition, \code{partition_power(pi, k)}.  The power
-  of a partition corresponds to the $k$-th power of a permutation with
-  cycle structure $\pi$.
-
-\item Sign of a partition, \code{partition_sign( pi ) } This means the
-  sign of a permutation with cycle structure given by the partition
-  pi.
-
-\item Associated partition, \code{partition_associated( pi )} The
-  ``associated'' (also called ``conjugate'' in the literature)
-  partition of the partition pi which is obtained by transposing the
+  \code{number_of_partition_tuples}.
+  A $k$-tuple of partitions is represented by a list of all $k$-tuples 
+  of partitions which together form a partition of $n$. 
+
+\item Powers of a partition, \code{partition_power(pi, k)}.
+  The power of a partition corresponds to the $k$-th power of a 
+  permutation with cycle structure $\pi$.
+
+\item Sign of a partition, \code{partition_sign( pi ) }
+  This means the sign of a permutation with cycle structure given by the 
+  partition pi.
+
+\item Associated partition, \code{partition_associated( pi )}
+  The ``associated'' (also called ``conjugate'' in the literature) 
+  partition of the partition pi which is obtained by transposing the 
   corresponding Ferrers diagram.
 
-\item Ferrers diagram, \code{ferrers_diagram}.  Analogous to the Young
-  diagram of an irredicible representation of $S_n$.  \end{itemize}
+\item Ferrers diagram, \code{ferrers_diagram}.
+  Analogous to the Young diagram of an irredicible representation 
+  of $S_n$.
+  \end{itemize}
 
 Related functions:
@@ -266,5 +259,5 @@
         [1, 1, 2, 5, 14, 42, 132]
         sage: maxima.eval("-(1/2)*taylor (sqrt (1-4*x^2), x, 0, 15)")
-        '-1/2+x^2+x^4+2*x^6+5*x^8+14*x^10+42*x^12+132*x^14'
+        '-1/2 + x^2 + x^4 + 2*x^6 + 5*x^8 + 14*x^10 + 42*x^12 + 132*x^14'
         sage: [catalan_number(i) for i in range(-7,7) if i != -1]
         [0, 0, 0, 0, 0, 0, 1, 1, 2, 5, 14, 42, 132]
@@ -294,5 +287,5 @@
         [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0]
         sage: maxima.eval("taylor (2/(exp(x)+exp(-x)), x, 0, 10)")
-        '1-x^2/2+5*x^4/24-61*x^6/720+277*x^8/8064-50521*x^10/3628800'
+        '1 - x^2/2 + 5*x^4/24 - 61*x^6/720 + 277*x^8/8064 - 50521*x^10/3628800'
         sage: [euler_number(i)/factorial(i) for i in range(11)]
         [1, 0, -1/2, 0, 5/24, 0, -61/720, 0, 277/8064, 0, -50521/3628800]
Index: sage/combinat/sloane_functions.py
===================================================================
--- sage/combinat/sloane_functions.py	(revision 4064)
+++ sage/combinat/sloane_functions.py	(revision 3537)
@@ -35,9 +35,4 @@
     sage: a
     The integer sequence tau(n), which is the number of divisors of n.
-
-TESTS:
-    sage: a = sloane.A000001;
-    sage: a == loads(dumps(a))
-    True
 
 AUTHORS:
@@ -99,5 +94,4 @@
 from sage.misc.misc import srange
 from sage.rings.integer_ring import ZZ
-import sage.calculus.all as calculus
 Integer = ZZ
 
@@ -117,9 +111,4 @@
     def _repr_(self):
         raise NotImplementedError
-
-    def __cmp__(self, other):
-        if not isinstance(other, SloaneSequence):
-            return cmp(type(self), type(other))
-        return cmp(repr(self), repr(other))
 
     def __call__(self, n):
@@ -3397,5 +3386,5 @@
 
     def _eval(self, n):
-        return arith.binomial(n, int(calculus.floor(n//2)))
+        return arith.binomial(n,arith.floor(n//2))
 
 class A000292(SloaneSequence):
Index: sage/crypto/cipher.py
===================================================================
--- sage/crypto/cipher.py	(revision 4005)
+++ sage/crypto/cipher.py	(revision 2447)
@@ -28,7 +28,4 @@
 	self._key = key
 	
-    def __eq__(self, right):
-        return type(self) == type(right) and self._parent == right._parent and self._key == right._key
-
     def __repr__(self):
 	return str(self._key)
Index: sage/crypto/classical.py
===================================================================
--- sage/crypto/classical.py	(revision 4005)
+++ sage/crypto/classical.py	(revision 2784)
@@ -44,11 +44,4 @@
             sage: e(m)
             GSVXZGRMGSVSZG
-
-        TESTS:
-            sage: M = AlphabeticStrings()
-            sage: E = SubstitutionCryptosystem(M)
-            sage: E == loads(dumps(E))
-            True
-
         """
         if not isinstance(S, StringMonoid_class):
@@ -148,11 +141,4 @@
             sage: e(S("THECATINTHEHAT"))
             TAHEHTNITACEHT
-
-        EXAMPLES:
-            sage: S = AlphabeticStrings()
-            sage: E = TranspositionCryptosystem(S,14)
-            sage: E == loads(dumps(E))
-            True
-
         """
         if not isinstance(S, StringMonoid_class):
@@ -249,11 +235,4 @@
             sage: e(S("THECATINTHEHAT"))
             TIGFEYOUBQOSMG
-
-        TESTS:
-            sage: S = AlphabeticStrings()
-            sage: E = VigenereCryptosystem(S,14)
-            sage: E == loads(dumps(E))
-            True
-            
         """
         if not isinstance(S, StringMonoid_class):
Index: sage/crypto/classical_cipher.py
===================================================================
--- sage/crypto/classical_cipher.py	(revision 4005)
+++ sage/crypto/classical_cipher.py	(revision 2688)
@@ -32,15 +32,6 @@
 	    sage: e(m)
 	    GSVXZGRMGSVSZG
-
-        TESTS:
-            sage: S = AlphabeticStrings()
-            sage: E = SubstitutionCryptosystem(S)
-            sage: E == loads(dumps(E))
-            True
         """
 	SymmetricKeyCipher.__init__(self, parent, key)
-
-    def __eq__(self, right):
-        return type(self) == type(right) and self.parent() == right.parent() and self.key() == right.key()
 
     def __call__(self, M):
@@ -93,12 +84,4 @@
 	    sage: e(m)
 	    EHTTACDNAEHTTAH
-
-
-        TESTS:
-            sage: S = AlphabeticStrings()
-            sage: E = TranspositionCryptosystem(S,14)
-            sage: E == loads(dumps(E))
-            True
-
         """
 	n = parent.block_length()
@@ -148,11 +131,4 @@
             sage: e(m)
             LOEMELXRTYIZHT
-
-        TESTS:
-            sage: S = AlphabeticStrings()
-            sage: E = VigenereCryptosystem(S,11)
-            sage: E == loads(dumps(E))
-            True
-
         """
 	SymmetricKeyCipher.__init__(self, parent, key)
Index: sage/crypto/cryptosystem.py
===================================================================
--- sage/crypto/cryptosystem.py	(revision 4005)
+++ sage/crypto/cryptosystem.py	(revision 2688)
@@ -42,13 +42,4 @@
 	  self._block_length = block_length
 	  self._period = period
-
-      def __eq__(self,right):
-            return type(self) == type(right) and  \
-                   self._cipher_domain == right._cipher_domain and \
-                   self._cipher_codomain == right._cipher_codomain and \
-                   self._key_space ==  right._key_space and \
-                   self._block_length == right._block_length and \
-                   self._period == right._period
-
       
       def plaintext_space(self):
Index: sage/crypto/stream.py
===================================================================
--- sage/crypto/stream.py	(revision 4005)
+++ sage/crypto/stream.py	(revision 2771)
@@ -33,10 +33,4 @@
             LFSR cryptosystem over Finite Field of size 2
 
-        TESTS:
-            sage: E = LFSRCryptosystem(FiniteField(2))
-	    sage: E == loads(dumps(E))
-            True
-
-
 	TODO: Implement LFSR cryptosytem for arbitrary rings. The current 
 	implementation if limitated to the finite field of 2 elements only 
@@ -51,7 +45,4 @@
         SymmetricKeyCryptosystem.__init__(self, S, S, None)
 	self._field = field
-
-    def __eq__(self,right):
-        return type(self) == type(right) and self._field == right._field
 
     def __call__(self, key):
Index: sage/crypto/stream_cipher.py
===================================================================
--- sage/crypto/stream_cipher.py	(revision 4005)
+++ sage/crypto/stream_cipher.py	(revision 2710)
@@ -44,12 +44,4 @@
             sage: m == e(e(m))
             True            
-
-        TESTS:
-            sage: FF = FiniteField(2)
-            sage: P.<x> = PolynomialRing(FF)
-            sage: E = LFSRCryptosystem(FF)
-            sage: E == loads(dumps(E))
-            True
-
         """
         SymmetricKeyCipher.__init__(self, parent, key = (poly, IS))
Index: sage/databases/conway.py
===================================================================
--- sage/databases/conway.py	(revision 3702)
+++ sage/databases/conway.py	(revision 1097)
@@ -2,47 +2,4 @@
 Frank Luebeck's tables of Conway polynomials over finite fields.
 """
-
-
-## On 3/29/07, David Joyner <wdjoyner@gmail.com> wrote:
-## > I guessed what you would do to create the *.bz2 file
-## > and I think it turned out to be right. (You did things the simplest way,
-## > as far as I can see.) The file is posted at
-## > http://sage.math.washington.edu/home/wdj/patches/conway_table.py.bz2
-## > I think what you did was (a) take the data file from
-## > http://www.math.rwth-aachen.de/~Frank.Luebeck/data/ConwayPol/CPimport.txt
-## > (b) renamed the file conway_table.py
-## > (c) used an editor to make a few changes to the first few and last
-## > few lines of the data file,
-## > (d) packed it using bzip2.
-## >
-## > I did this and placed the *bz2 file in the correct directory
-## > (as determined by conway.py). Here's a test
-## >
-## > sage: R = PolynomialRing(GF(2),"x")
-## > sage: R(ConwayPolynomials()[2][3])
-## > x^3 + x + 1
-## >
-## > If I am reading conway.py correctly then this test shows that the
-## > file I created is what you want.
-## >
-## > If you agree, then I will add the new data (you forwarded by
-## > separate emails) to it.
-## >
-## > Please let me know if this is reasonable.
-
-## Yes, you did exactly the right thing, which I verified as follows:
-
-## (1) delete SAGE_ROOT/data/conway_polynomials/*
-## (2) put your conway_polynomial.py.bz2 file in a new directory
-##      /home/was/s/data/src/conway/
-## (3) Start SAGE:
-## sage: c = ConwayPolynomials(read_only=False)
-## sage: c._init()       # builds database
-## sage: c.polynomial(3,10)
-## [2, 1, 0, 0, 2, 2, 2, 0, 0, 0, 1]
-## (4) restart and test:
-## sage: conway_polynomial(3,10)
-## x^10 + 2*x^6 + 2*x^5 + 2*x^4 + x + 2
-
 
 #*****************************************************************************
Index: sage/databases/cremona.py
===================================================================
--- sage/databases/cremona.py	(revision 4053)
+++ sage/databases/cremona.py	(revision 1097)
@@ -256,5 +256,4 @@
         sage: c.allcurves(11)
         {'a1': [[0, -1, 1, -10, -20], 0, 5], 'a3': [[0, -1, 1, 0, 0], 0, 5], 'a2': [[0, -1, 1, -7820, -263580], 0, 1]}
-
     """
     def __init__(self, read_only=True):
Index: sage/dsage/LICENSE.txt
===================================================================
--- sage/dsage/LICENSE.txt	(revision 3746)
+++ sage/dsage/LICENSE.txt	(revision 2888)
@@ -1,18 +1,14 @@
-##############################################################################
-#                                                                     
-#  DSAGE: Distributed SAGE                     
-#                                                                             
-#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
-#                                                                            
-#  Distributed under the terms of the GNU General Public License (GPL)        
-#
-#    This code 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
-#    General Public License for more details.
-#
-#  The full text of the GPL is available at:
-#
-#                  http://www.gnu.org/licenses/
-#
-##############################################################################
+# Distributed SAGE 
+# Copyright (C) 2006 Yi Qiang 
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+# This program 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 General Public License for more details.
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
Index: sage/dsage/README.txt
===================================================================
--- sage/dsage/README.txt	(revision 3852)
+++ sage/dsage/README.txt	(revision 2888)
@@ -53,5 +53,5 @@
 
         2)  Setting up a public key database
-            Authentication of clients is done solely based on public keys.
+            Authentication of users is done solely based on public keys.
             To grant a client access to the server, you must first add
             their username and public key to the file you specified in
@@ -128,5 +128,5 @@
             id, you can simply type:
                 
-                print job.result.job.job_id
+                print job.result.job.id
 
             This will print out the id of the job you submitted.  Also, the
Index: sage/dsage/all.py
===================================================================
--- sage/dsage/all.py	(revision 3901)
+++ sage/dsage/all.py	(revision 3634)
@@ -1,26 +1,12 @@
-##############################################################################
-#                                                                     
-#  DSAGE: Distributed SAGE                     
-#                                                                             
-#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
-#                                                                            
-#  Distributed under the terms of the GNU General Public License (GPL)        
-#
-#    This code 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
-#    General Public License for more details.
-#
-#  The full text of the GPL is available at:
-#
-#                  http://www.gnu.org/licenses/
-#
-##############################################################################
+"""nodoctest
+"""
 from sage.dsage.dsage import dsage
-from sage.dsage.dist_functions.all import *
+#from sage.dsage.dist_functions.all import *
 
-def DSage(server=None, port=None, username=None, pubkey_file=None, privkey_file=None):
+def DSage(server=None, port=8081, username=None, 
+          pubkey_file=None, privkey_file=None):
     from sage.dsage.interface.dsage_interface import BlockingDSage
     return BlockingDSage(server=server, port=port, username=username,
                          pubkey_file=pubkey_file, privkey_file=privkey_file)
+    
 
Index: age/dsage/database/clientdb.py
===================================================================
--- sage/dsage/database/clientdb.py	(revision 3866)
+++ 	(revision )
@@ -1,229 +1,0 @@
-##############################################################################
-#                                                                     
-#  DSAGE: Distributed SAGE                     
-#                                                                             
-#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
-#                                                                            
-#  Distributed under the terms of the GNU General Public License (GPL)        
-#
-#    This code 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
-#    General Public License for more details.
-#
-#  The full text of the GPL is available at:
-#
-#                  http://www.gnu.org/licenses/
-#
-##############################################################################
-
-import datetime
-import os
-import sqlite3 as sqlite
-
-from twisted.python import log
-
-import sage.dsage.database.sql_functions as sql_functions
-from sage.dsage.misc.config import get_conf
-
-class ClientDatabase(object):
-    """
-    This class defines the ClientDatabase which is used to store user 
-    authentication credentials and other information.
-    
-    """
-    
-    TABLENAME = 'clients'
-    
-    CREATE_USER_TABLE = """CREATE TABLE %s 
-    (
-     id integer PRIMARY KEY,
-     username text NOT NULL UNIQUE, 
-     public_key text NOT NULL UNIQUE,
-     creation_time timestamp, 
-     access_time timestamp,
-     last_login timestamp,
-     connected BOOL,
-     enabled BOOL DEFAULT 1
-    )
-    """ % TABLENAME
-           
-    def __init__(self, test=False):
-        """
-        Parameters:
-        test -- set to true if you would like to do testing.
-        
-        """
-        
-        self.conf = get_conf(type='clientdb')
-        self.tablename = self.TABLENAME
-        if test:
-            self.db_file = 'clientdb_test.db'
-        else:
-            self.db_file = self.conf['db_file']
-            if not os.path.exists(self.db_file):
-                dir, file = os.path.split(self.db_file)
-                if not os.path.isdir(dir):
-                    os.mkdir(dir)
-        self.con = sqlite.connect(self.db_file,
-                    detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES)
-        self.con.text_factory = str
-        
-        if sql_functions.table_exists(self.con, self.tablename) is None:
-            sql_functions.create_table(self.con, 
-                                       self.tablename,
-                                       self.CREATE_USER_TABLE)
-            self.con.commit()
-    
-    def _shutdown(self):
-        self.con.commit()
-        self.con.close()
-        
-    def get_user_and_key(self, username):
-        """
-        Returns a tuple containing the username and public key.
-        
-        """
-        
-        query = """SELECT username, public_key FROM clients WHERE username = ?"""
-        
-        cur = self.con.cursor()
-        cur.execute(query, (username,))
-        result = cur.fetchone()
-        
-        return result
-    
-    def get_user(self, username):
-        """
-        Returns a tuple containing all of the clients information.
-        
-        WARNING: ORDER OF RETURNED TUPLE MIGHT CHANGE
-        
-        """
-        
-        query = """SELECT * FROM clients WHERE username = ?"""
-        cur = self.con.cursor()
-        cur.execute(query, (username,))
-        result = cur.fetchone()
-        
-        return result
-    
-    def add_user(self, username, pubkey):
-        """
-        Adds a user to the database.
-        
-        """
-        
-        query = """INSERT INTO clients 
-                   (username, public_key, creation_time) 
-                   VALUES (?, ?, ?)
-                """
-        
-        try:
-            f = open(pubkey)
-            type_, key = f.readlines()[0].split()[:2]
-            f.close()
-            if not type_ == 'ssh-rsa':
-                raise TypeError
-        except IOError:
-            key = pubkey
-            
-        cur = self.con.cursor()
-        cur.execute(query, (username, key, datetime.datetime.now()))
-        self.con.commit()        
-    
-    def del_user(self, username):
-        """
-        Deletes a user from the database.
-        
-        """
-        
-        query = """DELETE FROM clients WHERE username = ?"""
-        self.con.execute(query, (username,))
-        self.con.commit()        
-    
-    def set_enabled(self, username, enabled=True):
-        """
-        Enables/Disables a clients account.
-        
-        Parameters:
-        username -- str
-        enabled -- bool     
-        """
-            
-        query = """UPDATE clients
-        SET enabled = ?
-        WHERE username = ?
-        """
-        
-        self.con.execute(query, (enabled, username))
-        self.con.commit()
-    
-    def get_enabled(self, username):
-        """
-        Returns whether or not a user account is enabled.
-        
-        """
-        
-        query = """SELECT enabled FROM clients WHERE username = ?"""
-        cur = self.con.cursor()
-        cur.execute(query, (username,))
-        result = cur.fetchone()
-        
-        return bool(result[0])
-        
-    def set_parameter(self, username, parameter, value):
-        """
-        Sets a particular parameter for the given username.
-        
-        """
-        
-        query = """UPDATE clients
-        SET %s = ?
-        WHERE username = ?
-        """ % (parameter)
-        
-        self.con.execute(query, (value, username))
-        self.con.commit()
-    
-    def get_parameter(self, username, parameter):
-        """
-        Returns a particular parameter for the given username.
-        
-        """
-        
-        query = """SELECT %s FROM clients WHERE username = ?""" % parameter
-        cur = self.con.cursor()
-        cur.execute(query, (username,))
-        result = cur.fetchone()
-        
-        return result[0]
-    
-    def set_connected(self, username, connected=True):
-        self.set_parameter(username, 'connected', connected)
-    
-    def update_login_time(self, username):
-        """
-        Updates the last_login time of the user.
-        
-        """
-        
-        query = """UPDATE clients
-        SET last_login = ?
-        WHERE username = ?
-        """
-        
-        self.con.execute(query, (datetime.datetime.now(), username,))
-        self.con.commit()
-    
-    def get_client_list(self):
-        """
-        Returns a list of clients connected.
-        
-        """
-        
-        query = """SELECT username from clients WHERE connected"""
-        cur = self.con.cursor()
-        cur.execute(query)
-        
-        return [result[0] for result in cur.fetchall()]
Index: sage/dsage/database/job.py
===================================================================
--- sage/dsage/database/job.py	(revision 3866)
+++ sage/dsage/database/job.py	(revision 3019)
@@ -15,5 +15,4 @@
 #
 #                  http://www.gnu.org/licenses/
-#
 ############################################################################
 
@@ -23,17 +22,18 @@
 import bz2
 import os
-import copy
+
+from twisted.spread import pb
 
 from persistent import Persistent
 
 class Job(Persistent):
+    r"""
+    Defines a Job that gets distributed to clients.
+    
     """
-    Defines a Job that gets distributed to clients.
-    
-    """
-
-    def __init__(self, id_=None, name=None, code=None, parent=None, 
-                 username=None, type_='sage'):
-        """
+
+    def __init__(self, id=None, name=None, file=None, parent=None, 
+                 author=None, type='sage'):
+        r"""
         Creates a new job.
 
@@ -41,7 +41,7 @@
         name -- job name 
         id -- job id (must be unique)
-        code -- job code
+        file -- job file
         parent -- sets if the job is a parent job
-        username -- author of the job (not neccesarily unique)
+        author -- author of the job (not neccesarily unique)
         type -- the type of the job (file, string, generator)
                 defaults to string
@@ -52,39 +52,30 @@
 
         # Job keywords
-        self.jdict['job_id'] = id_
         self.jdict['name'] = name
-        self.jdict['code'] = code
-        self.jdict['username'] = username
+        self.jdict['id'] = id
+        self.jdict['num'] = None
+        self.jdict['file'] = file
+        self.jdict['parent'] = parent
+        self.jdict['author'] = author
+        self.jdict['creation_time'] = datetime.datetime.now()
+        self.jdict['finish_time'] = None
+        self.jdict['updated_time'] = None
+
+        # Valid status keywords:
+        # new, completed, incomplete, processing
+        self.jdict['status'] = 'new' 
+ 
+        self.jdict['children'] = []
+        self.jdict['type'] = type
+        self.jdict['result'] = None # result should be a pickled object
+        self.jdict['failures'] = 0
+        self.jdict['killed'] = False
         self.jdict['data'] = []
         self.jdict['output'] = ''
         self.jdict['worker_info'] = None
-        # Valid status keywords:
-        # new, completed, incomplete, processing
-        self.jdict['status'] = 'new' 
-        self.jdict['creation_time'] = datetime.datetime.now()
-        self.jdict['update_time'] = None
-        self.jdict['finish_time'] = None
-        self.jdict['killed'] = False
-        self.jdict['type'] = type_
-        self.jdict['result'] = None # result should be a pickled object
-        self.jdict['failures'] = 0
-        self.jdict['verifiable'] = False # is this job easily verified?
-        
-        # These might become deprecated
-        self.jdict['parent'] = parent
-        self.jdict['children'] = []
 
     def __str__(self):
         return str(self.jdict)
-    
-    def __setattr__(self, name, value):
-        if name == 'jdict':
-            if not self.__dict__.has_key('jdict'):
-                self.__dict__[name] = value
-            else:
-                raise ValueError, 'Do not reassign Job.jdict.'
-        else:
-            Persistent.__setattr__(self, name, value)
-        
+
     def num_of_children(self):
         return len(self.jdict['children'])
@@ -98,29 +89,38 @@
     name = property(fget=get_name, fset=set_name, fdel=None, doc='Job name')
 
-    def get_code(self):
-        return self.jdict['code']
-    def set_code(self, value):
+    def get_file(self):
+        return self.jdict['file']
+    def set_file(self, value):
         if not isinstance(value, str):
             raise TypeError
-        self.jdict['code'] = value
-    code = property(fget=get_code, fset=set_code, fdel=None,
-                    doc='Job code')
+        self.jdict['file'] = value
+    file = property(fget=get_file, fset=set_file, fdel=None,
+                    doc='Job file')
 
     def get_id(self):
-        return self.jdict['job_id']
+        return self.jdict['id']
     def set_id(self, value):
         if not isinstance(value, str):
             raise TypeError
-        self.jdict['job_id'] = value
-    job_id = property(fget=get_id, fset=set_id, fdel=None, doc='Job ID')
+        self.jdict['id'] = value
+    id = property(fget=get_id, fset=set_id, fdel=None, doc='Job ID')
+
+    def get_num(self):
+        if self.id is None:
+            return None
+        s = self.id.find('_') + 1
+        return int(self.id[s:])
+    def set_num(self):
+        pass
+    num = property(fget=get_num, fset=set_num, fdel=None, doc='Job Number')
     
     def get_status(self):
         return self.jdict['status']
     def set_status(self, value):
-        # statuses = ['new', 'completed', 'incomplete', 'processing']
-        # if not value in statuses:
-        #    raise TypeError
-        #if value == 'completed':
-        #    self.finish_time = datetime.datetime.now()
+        statuses = ['new', 'completed', 'incomplete', 'processing']
+        if not value in statuses:
+            raise TypeError
+        if value == 'completed':
+            self.finish_time = datetime.datetime.now()
         self.jdict['status'] = value
     status = property(fget=get_status, fset=set_status, fdel=None, 
@@ -159,9 +159,10 @@
                       doc='Job output')
 
-    def get_username(self):
-        return self.jdict['username']
-    def set_username(self, value):
-        self.jdict['username'] = value
-    username = property(fget=get_username, fset=set_username, fdel=None,
+    def get_author(self):
+        return self.jdict['author']
+    def set_author(self, value):
+        
+        self.jdict['author'] = value
+    author = property(fget=get_author, fset=set_author, fdel=None,
                       doc='Job author')
    
@@ -175,16 +176,15 @@
                            fdel=None, doc='Job finish time')
 
-    def get_update_time(self):
-        return self.jdict['update_time']
-    def set_update_time(self, value):
+    def get_updated_time(self):
+        return self.jdict['updated_time']
+    def set_updated_time(self, value):
         if not isinstance(value, datetime.datetime):
             raise TypeError
-        self.jdict['update_time'] = value
-    update_time = property(fget=get_update_time, fset=set_update_time,
+        self.jdict['updated_time'] = value
+    updated_time = property(fget=get_updated_time, fset=set_updated_time,
                             fdel=None, doc='Job updated time')
    
     def get_creation_time(self):
         return self.jdict['creation_time']
-
     def set_creation_time(self, value):
         if not isinstance(value, datetime.datetime):
@@ -229,14 +229,11 @@
     worker_info = property(fget=get_worker_info, fset=set_worker_info,
                            fdel=None, doc='Worker info')
-      
-    def get_verifiable(self):
-        return self.jdict['verifiable']
-    def set_verifiable(self, value):
-        if not isinstance(value, bool):
-            raise TypeError
-        self.jdict['verifiable'] = value         
+    
+    def get_data(self):
+        return self.jdict['data']
+    data = property(fget=get_data, fset=None, fdel=None, doc='Job data.')            
     
     def attach(self, var, obj, file_name=None):
-        """
+        r"""
         Attaches an object to a job.
         
@@ -251,5 +248,5 @@
             try:
                 s = open(file_name, 'rb').read()
-                s = zlib.compress(s)
+                s = zlib.compress(f)
             except:
                 print 'Unable to load %s. ' % file_name
@@ -259,11 +256,11 @@
                 s = cPickle.dumps(obj, 2)
                 s = zlib.compress(s)
-            except cPickle.PicklingError:
-                print 'Unable to attach your object.'
+            except PicklingError:
+                print 'Unable to attach yor object.'
                 return
         self.jdict['data'].append((var, s, 'object'))
         
     def attach_file(self, file_name):
-        """
+        r"""
         Attach a file to a job.
         
@@ -273,6 +270,10 @@
         """
         
-        f = open(file_name, 'rb').read()
-        f = zlib.compress(f)
+        try:
+            f = open(file_name, 'rb').read()
+            f = zlib.compress(f)
+        except:
+            print 'Unable to read file.'
+            return
         
         # Strip out any hard coded path in the file name
@@ -281,16 +282,19 @@
     
     def pickle(self):
-        """
+        r"""
         Returns a pickled representation of self.
         
         """
         
-        s = cPickle.dumps(self, 2)
-        s = zlib.compress(s)
-
+        try:
+            s = cPickle.dumps(self, 2)
+            s = zlib.compress(s)
+        except:
+            print 'Error pickling self'
+            return
         return s
     
     def unpickle(self, pickled_job):
-        """
+        r"""
         Returns the unpickled version of myself.
         
@@ -298,38 +302,2 @@
         
         return cPickle.loads(zlib.decompress(pickled_job))
-    
-    def reduce(self):
-        """
-        Returns a reduced form of Job.jdict to be sent over the network.
-        
-        """
-        
-        # TODO: Figure out what attributes are safe to delete
-        
-        # dump and compress the data of the job
-        jdict = copy.deepcopy(self.jdict)
-        jdict['data'] = cPickle.dumps(self.jdict['data'], 2)
-        jdict['data'] = zlib.compress(jdict['data'])
-        
-        return jdict
-
-def expand_job(jdict):
-    """
-    This method recreates a Job object given a jdict.
-    
-    """
-    
-    if jdict is None:
-        return None
-    
-    job = Job()
-    
-    # decompress and load data
-    try:
-        jdict['data'] = zlib.decompress(jdict['data'])
-        jdict['data'] = cPickle.loads(jdict['data'])
-    except:
-        jdict['data'] = None
-    job.jdict.update(jdict)
-    
-    return job
Index: sage/dsage/database/jobdb.py
===================================================================
--- sage/dsage/database/jobdb.py	(revision 3895)
+++ sage/dsage/database/jobdb.py	(revision 3017)
@@ -15,13 +15,11 @@
 #
 #                  http://www.gnu.org/licenses/
-#
 ############################################################################
 
+import sys
 import datetime
 import os
+import ConfigParser
 import random
-import string
-import time
-import sqlite3 
 
 from twisted.python import log
@@ -29,43 +27,31 @@
 from ZODB import FileStorage, DB
 from BTrees import OOBTree
+from persistent import Persistent 
 import transaction
 
+import sqlite3 as sqlite
+
 from sage.dsage.database.job import Job
-import sage.dsage.database.sql_functions as sql_functions
-from sage.dsage.misc.config import get_conf
-
-class JobDatabase(object):
-    """
-    Implementation of the job database. 
-    Common methods between the implementations should go here.
-    
-    """
-    
-    def __init__(self):
-        self.conf = get_conf(type='jobdb')
-        self.db_file = self.conf['db_file']
-        self.job_failure_threshold = int(self.conf['job_failure_threshold'])
-        self.log_file = self.conf['log_file']
-        self.log_level = int(self.conf['log_level'])
-        self.prune_in_days = int(self.conf['prune_in_days'])
-        
-    def random_string(self, length=10):
-        """
-        Returns a random string
-        
-        Parameters:
-            length -- the length of the string
-        
-        """
-        
-        random.seed()
-        l = list((length*length) * (string.letters + string.digits)) 
-        random.shuffle(l)
-        s = ''.join(random.sample(l, length))
-
-        return s
-    
-class JobDatabaseZODB(JobDatabase):
-    """
+
+DSAGE_DIR = os.path.join(os.getenv('DOT_SAGE'), 'dsage')
+# Begin reading configuration
+try:
+    conf_file = os.path.join(DSAGE_DIR, 'server.conf')
+    config = ConfigParser.ConfigParser()
+    config.read(conf_file)
+
+    DB_FILE = os.path.expanduser(config.get('db', 'db_file'))
+    PRUNE_IN_DAYS = config.getint('db', 'prune_in_days')
+    STALE_IN_DAYS = config.getint('db', 'stale_in_days')
+    FAILURE_THRESHHOLD = config.getint('db', 'failure_threshhold')
+    LOG_FILE = config.get('db_log', 'log_file')
+    LOG_LEVEL = config.getint('db_log', 'log_level')
+except:
+    print "Error reading '%s', please run dsage.setup() or fix manually"%conf_file
+    sys.exit(-1)
+# End reading configuration
+
+class JobDatabaseZODB(object):
+    r"""
     Implementation of DSage's database using ZODB.
 
@@ -76,18 +62,9 @@
     """
 
-    # The following effectively turns of the ZODB logger, which is OK for us. 
-    # Without this, one gets this annoying error message a lot:
-    #       No handlers could be found for logger "ZODB.FileStorage"
-    import logging
-    logging.getLogger("ZODB.FileStorage").setLevel(10000000)
-    logging.getLogger("ZODB.lock_file").setLevel(10000000)
-    logging.getLogger("ZODB.Connection").setLevel(10000000)
-    
     def __init__(self, test=False, read_only=False):
-        JobDatabase.__init__(self)
         if test:
             self.db_file = 'test_db.db'
         else:
-            self.db_file = self.DB_FILE
+            self.db_file = DB_FILE
             if not os.path.exists(self.db_file):
                 dir, file = os.path.split(self.db_file)
@@ -95,6 +72,5 @@
                     os.mkdir(dir)
         if read_only:
-            self.storage = FileStorage.FileStorage(self.db_file,
-                                                   read_only=True)
+            self.storage = FileStorage.FileStorage(self.db_file, read_only=True)
         else:
             self.storage = FileStorage.FileStorage(self.db_file)
@@ -116,9 +92,9 @@
         self.completed_jobdb = self.dbroot['completed_jobdb']
 
-        if self.get_job_by_id('GLOBALS') == None:
+        if self.getJobByID('GLOBALS') == None:
             self.__init_globals()
 
     def _shutdown(self):
-        """
+        r"""
         Shuts down the database by closing all DB connections and 
         storages. 
@@ -129,29 +105,46 @@
         self.db.close()
 
-    def get_next_job_id(self):
-        """
-        Increments job_id by one and returns the current job_id
-        
-        """
-
-        gdict = self.__retrieve_globals()
+    def getJobID(self):
+        r"""
+        Increments jobID by one and returns the current jobID
+        
+        """
+
+        gdict = self.__retrieveGlobals()
         jobNUM = gdict['next_job_num']
         gdict['next_job_num'] += 1
-        job_id = self.random_string(10) + '_' + '%s' % jobNUM
-        self.store_job(gdict)
-        if self.log_level > 1:
+        jobID = self.random_string(10) + '_' + '%s' % jobNUM
+        self.storeJob(gdict)
+        if LOG_LEVEL > 1:
             log.msg('[DB] Incremented job num to: ', jobNUM)
             
-        return job_id
+        return jobID
+    
+    def random_string(self, length):
+        r"""
+        Returns a random string
+        
+        Parameters:
+            length -- the length of the string
+        
+        """
+        
+        random.seed()
+        letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
+        l = list(10 * letters) 
+        random.shuffle(l)
+        s = ''.join(random.sample(l, length))
+
+        return s
    
-    def __retrieve_globals(self):
-        return self.get_job_by_id('GLOBALS')
+    def __retrieveGlobals(self):
+        return self.getJobByID('GLOBALS')
 
     def __init_globals(self):
         gdict = dict(next_job_num = 1)
-        self.store_job(gdict)
-    
-    def get_job(self):
-        """
+        self.storeJob(gdict)
+    
+    def getJob(self):
+        r"""
         Returns the first non completed job in the job database.
 
@@ -161,5 +154,5 @@
 
         """
-        for job_id, job in self.jobdb.iteritems():
+        for jobID, job in self.jobdb.iteritems():
             try:
                 if isinstance(job, Job) and job.status == 'new':
@@ -168,23 +161,23 @@
                 return None
 
-    def get_job_by_id(self, job_id):
-        """
+    def getJobByID(self, jobID):
+        r"""
         Returns a job given a job id.
 
         Parameters:
-        job_id -- the job id (int)
-        
-        """
-        if not self.has_job(job_id):
+        jobID -- the job id (int)
+        
+        """
+        if not self.hasJob(jobID):
             return None
         else:
-            return self.jobdb[job_id]
-
-    def get_jobs_by_username(self, username, is_active, job_name=None):
-        """
+            return self.jobdb[jobID]
+
+    def getJobsByAuthor(self, author, is_active, job_name=None):
+        r"""
         Returns jobs created by author. 
 
         Parameters:
-        username -- the username name (str)
+        author -- the author name (str)
         is_active -- when set to true, only return active jobs (bool)
         job_name -- the job name to return (default=None)
@@ -194,24 +187,24 @@
         if is_active:
             if job_name:
-                jobs = [job for job in self.get_active_jobs()
-                        if (job.username == username and job.name == job_name)]
+                jobs = [job for job in self.getActiveJobs()
+                        if (job.author == author and job.name == job_name)]
             else:
-                jobs = [job for job in self.get_active_jobs()
-                        if job.username == username]
+                jobs = [job for job in self.getActiveJobs()
+                        if job.author == author]
 
         else:
             if job_name:
-                jobs = [job for job in self.get_jobs_list()
-                        if (job.username == username and job.name == job_name)]
+                jobs = [job for job in self.getJobsList()
+                        if (job.author == author and job.name == job_name)]
             else:
-                jobs = [job for job in self.get_jobs_list() 
-                        if job.username == username]
-
-        if self.log_level > 3:
-            log.msg('[JobDatabaseZODB, get_jobs_by_username] ', jobs)
+                jobs = [job for job in self.getJobsList() 
+                        if job.author == author]
+
+        if LOG_LEVEL > 3:
+            log.msg('[JobDatabaseZODB, getJobsByAuthor] ', jobs)
         return jobs
 
-    def store_job(self, job):
-        """
+    def storeJob(self, job):
+        r"""
         Stores a job in the job database.
 
@@ -228,48 +221,48 @@
         if isinstance(job, dict):
             if job.has_key('next_job_num'):
-                # log.msg('[DB, store_job] Setting job_id to GLOBALS')
-                job_id = 'GLOBALS'
+                # log.msg('[DB, storeJob] Setting jobID to GLOBALS')
+                jobID = 'GLOBALS'
         elif isinstance(job, Job):
-            job_id = job.job_id
-            if not isinstance(job_id, str):
-                job_id = self.get_next_job_id()
-            job.update_time = datetime.datetime.now()
+            jobID = job.id
+            if not isinstance(jobID, str):
+                jobID = self.getJobID()
+            job.updated_time = datetime.datetime.now()
         else:
             raise TypeError
         
-        self.jobdb[job_id] = job
+        self.jobdb[jobID] = job
         # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
         # Need this hack to notify ZODB that the dict was modified
         # WITHOUT IT CHANGES WILL NOT BE WRITTEN BACK TO DISK
-        if job_id != 'GLOBALS':
+        if jobID != 'GLOBALS':
             job._p_changed = True
         # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
         transaction.commit()
-        if self.log_level > 0:
-            log.msg("[DB] Stored job %s" % (job_id))
-        
-        return job_id
-
-    def remove_job(self, job_id):
-        """
+        if LOG_LEVEL > 0:
+            log.msg("[DB] Stored job %s" % (jobID))
+        
+        return jobID
+
+    def removeJob(self, jobID):
+        r"""
         Removes a job from the database.
         
         Parameters:
-         job_id -- job id (int)
+         jobID -- job id (int)
         
         """
         
         try:
-            del self.jobdb[job_id]
-            if self.log_level > 0:
-                log.msg('[JobDB] Removed job %s from jobdb' % (job_id))
+            del self.jobdb[jobID]
+            if LOG_LEVEL > 0:
+                log.msg('[JobDB] Removed job %s from jobdb' % (jobID))
             transaction.commit()
-            return job_id
+            return jobID
         except:
             log.msg('[JobDB] Failure removing a job.')
             raise
 
-    def get_active_jobs(self):
-        """
+    def getActiveJobs(self):
+        r"""
         Returns a list containing active jobs, i.e.
         jobs that are currentl being processed.
@@ -277,18 +270,18 @@
         """
 
-        return [job for job in self.get_jobs_list() 
+        return [job for job in self.getJobsList() 
                 if job.status == 'processing']
   
-    def has_job(self, job_id):
-        """
+    def hasJob(self, jobID):
+        r"""
         Checks if the database contains a job corresponding to job id. 
 
         Parameters:
-        job_id -- the job id (int)
+        jobID -- the job id (int)
 
         """
         
         # For some reason has_key returns 0/1 versus True/False
-        b = self.jobdb.has_key(job_id)
+        b = self.jobdb.has_key(jobID)
         if b > 0:
             return True
@@ -296,6 +289,6 @@
             return False
 
-    def get_jobs_list(self):
-        """
+    def getJobsList(self):
+        r"""
         Returns an ordered list of all the jobs in 
         the database.
@@ -305,14 +298,14 @@
         sorted_list = []
 
-        for job_id, job in self.jobdb.iteritems():
-            if job_id == 'GLOBALS': # Skip the GLOBALS job
+        for jobID, job in self.jobdb.iteritems():
+            if jobID == 'GLOBALS': # Skip the GLOBALS job
                 continue
-            sorted_list.append((job.job_id, job))
+            sorted_list.append((job.num, job))
         sorted_list.sort()
         
         return [job[1] for job in sorted_list]
 
-    def get_completed_jobs_list(self):
-        """
+    def getCompletedJobsList(self):
+        r"""
         Returns an ordered list of all the completed 
         jobs in the database.
@@ -320,25 +313,25 @@
         """
 
-        return [job for job in self.get_jobs_list() 
+        return [job for job in self.getJobsList() 
                 if job.status == 'completed']
 
-    def get_in_complete_jobs_list(self):
-        """
+    def getIncompleteJobsList(self):
+        r"""
         Returns an ordered list of jobs marked as incomplete.
         
         """
 
-        return [job for job in self.get_jobs_list() 
+        return [job for job in self.getJobsList() 
                 if job.status == 'incomplete']
 
-    def get_killed_jobs_list(self):
-        """
+    def getKilledJobsList(self):
+        r"""
         Returns a list of killed jobs.
         
         """
-        return [job for job in self.get_jobs_list() if job.killed]
-
-    def new_job(self, job):
-        """
+        return [job for job in self.getJobsList() if job.killed]
+
+    def newJob(self, job):
+        r"""
         Stores a new job in the database.
         
@@ -348,294 +341,16 @@
         """
         
-        job_id = self.get_next_job_id()
-        job.job_id = job_id
-        
-        return self.store_job(job)
-
-class JobDatabaseSQLite(JobDatabase):
-    """
-    Implementation of DSage's database using SQLite.
-
-    Parameters:
-    test -- set to true for unittesting purposes
-
-    """
-
-    # TODO: SQLite does *NOT* enforce foreign key constraints
-    # Must do manual checking.
-    
-    CREATE_JOBS_TABLE = """CREATE TABLE jobs 
-    (job_id TEXT NOT NULL UNIQUE,
-     name TEXT, 
-     username TEXT REFERENCES clients(username),
-     monitor_id TEXT REFERENCES monitors(uuid),
-     worker_info TEXT,
-     code TEXT,
-     data BLOB,
-     output TEXT,
-     result BLOB, 
-     status TEXT NOT NULL,
-     priority INTEGER DEFAULT 10,
-     type TEXT,
-     failures INTEGER DEFAULT 0, 
-     creation_time timestamp NOT NULL,
-     update_time timestamp,
-     finish_time timestamp,
-     verifiable BOOL,
-     killed BOOL DEFAULT 0 
-    );
-    """
-    
-    def __init__(self, test=False):
-        JobDatabase.__init__(self)
-        if test:
-            self.db_file = 'test_jobdb.db'
-        else:
-            if not os.path.exists(self.db_file):
-                dir, file = os.path.split(self.db_file)
-                if not os.path.isdir(dir):
-                    os.mkdir(dir)
-                    
-        self.tablename = 'jobs'
-        self.con = sqlite3.connect(
-                   self.db_file,
-                   detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
-        self.con.text_factory = str # Don't want unicode objects 
-        if not sql_functions.table_exists(self.con, self.tablename):
-            sql_functions.create_table(self.con,
-                                       self.tablename, 
-                                       self.CREATE_JOBS_TABLE)
-                                       
-    def __add_test_data(self):
-        INSERT_JOB = """INSERT INTO jobs 
-        (uid, 
-         username, 
-         code,
-         data, 
-         output, 
-         worker_id,
-         status, 
-         priority, 
-         creation_time, 
-         update_time, 
-         finish_time
-        ) 
-        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
-        """
-
-        dn = lambda: datetime.datetime.now() # short hand
-        D = [(self.random_string(), 1, None, None, None, 1, 
-             'new', 1, dn(), dn(), None),
-             (self.random_string(), 1, None, None, None, 1, 
-             0, 1, dn(), dn(), None),
-             (self.random_string(), 1, None, None, None, 1, 
-             0, 1, dn(), dn(), None)]
-             
-        log.msg('Sleeping for 0.5 second to test timestamps...')
-        time.sleep(0.5)
-        
-        D.extend([(self.random_string(), 1, None, None, None, 1, 
-                   0, 1, dn(), dn(), None),
-                  (self.random_string(), 1, None, None, None, 1, 
-                   0, 1, dn(), dn(), None),
-                  (self.random_string(), 1, None, None, None, 1, 
-                   0, 1, dn(), dn(), None)])
-
-        self.con.executemany(INSERT_JOB, D)
-        self.con.commit()
-        
-    def _shutdown(self):
-        self.con.commit()
-        self.con.close()
-    
-    def get_job(self, anonymous=False):
-        """
-        Returns the first unprocessed job of the highest priority.
-        
-        """
-
-        if anonymous:
-            query = "SELECT * FROM jobs WHERE status = 'new' AND killed = 0"
-        else:
-            query = "SELECT * FROM jobs WHERE status = 'new' AND killed = 0"
-        cur = self.con.cursor()
-        cur.execute(query)
-        jtuple = cur.fetchone()
-        
-        return self.create_jdict(jtuple, cur.description)
-    
-    def set_job_uuid(self, job_id, uuid):
-        query = "UPDATE jobs SET monitor_id=? WHERE job_id=?"
-        cur = self.con.cursor()
-        cur.execute(query, (uuid, job_id))
-        self.con.commit()
-        
-    def get_all_jobs(self):
-        query = "SELECT * from jobs"
-        cur = self.con.cursor()
-        cur.execute(query)
-        result = cur.fetchall()
-        
-        return [self.create_jdict(jtuple, cur.description) 
-                for jtuple in result]
-        
-    def get_job_by_id(self, job_id):
-        query = "SELECT * FROM jobs WHERE job_id = ?"
-        cur = self.con.cursor()
-        cur.execute(query, (job_id,)) # Need to cast it to int for SAGE
-        jtuple = cur.fetchone()
-        return self.create_jdict(jtuple, cur.description)
-    
-    def _get_jobs_by_parameter(self, key, value):
-        """
-        Returns a particular result given a key and value.
-        
-        """
-        
-        query = """SELECT * FROM jobs where %s = ?""" % (key)
-        cur = self.con.cursor()
-        cur.execute(query, (value,))
-        result = cur.fetchall()
-        
-        return [self.create_jdict(jtuple, cur.description) 
-                for jtuple in result]
-        
-    def _set_parameter(self, job_id, key, value):
-        query = """UPDATE jobs
-        SET %s=?
-        WHERE job_id=?""" % (key)
-        cur = self.con.cursor()
-        cur.execute(query, (value, job_id))
-        self.con.commit()
-        
-    def _update_value(self, job_id, key, value):
-        """
-        Sets the appropriate value for a job in the database.
-        
-        """
-        
-        query = """UPDATE jobs
-        SET %s=?
-        WHERE job_id=?
-        """ % (key)
-        cur = self.con.cursor()
-        if key == 'data' or key == 'result': # Binary objects
-            if value != None:
-                cur.execute(query, (sqlite3.Binary(value), job_id))
-        else:
-            cur.execute(query, (value, job_id))
-        self.con.commit()
-        
-    def store_job(self, jdict):
-        """
-        Stores a job based on information from Job.jdict.  
-        The keys of the dictionary should correspond to the columns in the
-        'jobs' table.
-        
-        Parameters:
-        job -- a sage.dsage.database.Job object
-        
-        """
-        
-        job_id = jdict['job_id']
-
-        if job_id is None: 
-            job_id = self.random_string()
-            if self.log_level > 3:
-                log.msg('[JobDB] Creating a new job with id:', job_id)
-            query = """INSERT INTO jobs 
-                    (job_id, status, creation_time) VALUES (?, ?, ?)"""
-            cur = self.con.cursor()
-            cur.execute(query, (job_id, 'new', datetime.datetime.now()))
-            self.con.commit()
-            
-        for k, v in jdict.iteritems():
-            try:
-                self._update_value(job_id, k, v)   
-            except (sqlite3.InterfaceError, 
-                    sqlite3.OperationalError,
-                    sqlite3.IntegrityError), msg:
-                if self.log_level > 3:
-                    log.msg('key: %s, value: %s' % (k, v))
-                    log.msg(msg)
-                continue    
-        
-        return self.get_job_by_id(job_id)
-    
-    def create_jdict(self, jtuple, row_description):
-        """
-        Creates a jdict out of a job_tuple.
-        
-        """
-        
-        if jtuple is None:
-            return None
-            
-        columns = [desc[0] for desc in row_description]
-        jdict = dict(zip(columns, jtuple))
-        
-        # Convert 0/1 into python booleans
-        jdict['killed'] = bool(jdict['killed'])
-        jdict['verifiable'] = bool(jdict['verifiable'])
-        
-        # Convert buffer objects back to string
-        jdict['data'] = str(jdict['data'])
-        jdict['result'] = str(jdict['result'])
-        
-        return jdict
-        
-    def get_killed_jobs_list(self):
-        """
-        Returns a list of jobs which have been marked as killed.
-        
-        """
-        query = "SELECT * from jobs where killed = 1 AND status <> 'completed'"
-        cur = self.con.cursor()
-        cur.execute(query)
-        killed_jobs = cur.fetchall()
-        return [self.create_jdict(jdict, cur.description) 
-                for jdict in killed_jobs]
-    
-    def get_jobs_by_username(self, username, active=True):
-        """
-        Returns a list of jobs belonging to 'username'
-        
-        """
-        
-        if active:
-            query = """SELECT * from jobs WHERE username = ? 
-            AND status IN ('new', 'processing')"""
-        else:
-            query = """SELECT * from jobs WHERE username = ? """
-        cur = self.con.cursor()
-        cur.execute(query, (username,))
-        
-        return [self.create_jdict(jtuple, cur.description) for jtuple in cur]
-        
-    def has_job(self, job_id):
-        """
-        Checks if the database contains a job with the given uid.
-        
-        """
-        
-        job = self.get_job_by_id(job_id)
-        if job is None:
-            return False
-        else:
-            return True
-    
-    def set_killed(self, job_id, killed=True):
-        self._update_value(job_id, 'killed', killed)
-    
-    def get_active_jobs(self):
-        return self._get_jobs_by_parameter('status', 'processing')
-        
+        jobID = self.getJobID()
+        job.id = jobID
+        
+        return self.storeJob(job)
+
 class DatabasePruner(object):
-    """
+    r"""
     DatabasePruner is responsible for cleaning out the database. 
     
     """    
     def __init__(self, jobdb):
-        """
+        r"""
         Parameters:
             jobdb -- a JobDatabase object
@@ -645,6 +360,6 @@
         self.jobdb = jobdb
     
-    def clean_old_jobs(self):
-        """
+    def cleanOldJobs(self):
+        r"""
         Cleans out jobs that are older than PRUNE_IN_DAYS days.
         
@@ -652,25 +367,28 @@
         
         log.msg('[DatabasePruner] Cleaning out old jobs...')
-        jobs = self.jobdb.get_jobs_list()
+        jobs = self.jobdb.getJobsList()
         for job in jobs:
-            delta =  datetime.datetime.now() - job.update_time
-            if delta > datetime.timedelta(self.jobdb.prune_in_days):
-                self.jobdb.remove_job(job.job_id)
-                log.msg('[DatabasePruner, clean_old_jobs] Deleted job ',
-                        job.job_id)
-    
-    def clean_failed_jobs(self):
-        """
+            delta =  datetime.datetime.now() - job.updated_time
+            if delta > datetime.timedelta(PRUNE_IN_DAYS):
+                self.jobdb.removeJob(job.id)
+                log.msg('[DatabasePruner, cleanOldJobs] Deleted job ',
+                        job.id)
+    
+    def cleanFailedJobs(self):
+        r"""
         Cleans out jobs which are marked as having failed. 
 
-        """
-        
-        jobs = self.jobdb.get_jobs_list()
+        Failure threshhold is set in FAILURE_THRESHHOLD, if a job 
+        exceeds this threshhold, we remove it from the job database.
+
+        """
+        
+        jobs = self.jobdb.getJobsList()
 
         for job in jobs:
-            if job.failures > self.jobdb.job_failure_threshold:
-                self.jobdb.remove_job(job.job_id)
+            if job.failures > FAILURE_THRESHHOLD:
+                self.jobdb.removeJob(job.id)
 
     def prune(self):
-        self.clean_old_jobs()
-        self.clean_failed_jobs()
+        self.cleanOldJobs()
+        self.cleanFailedJobs()
Index: age/dsage/database/monitordb.py
===================================================================
--- sage/dsage/database/monitordb.py	(revision 3866)
+++ 	(revision )
@@ -1,268 +1,0 @@
-##############################################################################
-#                                                                     
-#  DSAGE: Distributed SAGE                     
-#                                                                             
-#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
-#                                                                            
-#  Distributed under the terms of the GNU General Public License (GPL)        
-#
-#    This code 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
-#    General Public License for more details.
-#
-#  The full text of the GPL is available at:
-#
-#                  http://www.gnu.org/licenses/
-#
-##############################################################################
-
-import datetime
-import os
-import sqlite3 as sqlite
-
-from twisted.python import log
-
-import sage.dsage.database.sql_functions as sql_functions
-from sage.dsage.misc.config import get_conf
-
-class MonitorDatabase(object):
-    """
-    This table keeps track of workers.
-    
-    """
-        
-    CREATE_MONITOR_TABLE = """CREATE TABLE monitors 
-    (
-     uuid text NOT NULL UNIQUE,
-     hostname TEXT,
-     ip TEXT,
-     workers INTEGER,
-     sage_version text,
-     os text,
-     kernel_version TEXT,
-     cpus INTEGER, 
-     cpu_speed INTEGER,
-     cpu_model TEXT,
-     mem_total INTEGER,
-     mem_free INTEGER,
-     connected BOOL,
-     busy BOOL,
-     anonymous BOOL DEFAULT 0,
-     last_connection timestamp
-    )
-    """
-    
-    def __init__(self, test=False):
-        self.conf = get_conf(type='monitordb')
-        self.tablename = 'monitors'
-        if test:
-            self.db_file = 'monitordb-test.db'
-        else:
-            self.db_file = self.conf['db_file']
-            if not os.path.exists(self.db_file):
-                dir, file = os.path.split(self.db_file)
-                if not os.path.isdir(dir):
-                    os.mkdir(dir)
-        self.log_level = self.conf['log_level']
-        self.log_file = self.conf['log_file']
-        self.con = sqlite.connect(self.db_file,
-                    detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES)
-        self.con.text_factory = str
-        
-        if sql_functions.table_exists(self.con, self.tablename) is None:
-            sql_functions.create_table(self.con, 
-                                       self.tablename,
-                                       self.CREATE_MONITOR_TABLE)
-            self.con.commit()
-        
-    def _set_parameter(self, uuid, key, value):
-        query = """UPDATE monitors
-        SET %s=?
-        WHERE uuid=?""" % (key)
-        cur = self.con.cursor()
-        cur.execute(query, (value, uuid))
-        self.con.commit()
-    
-    def set_anonymous(self, uuid, anonymous=True):
-        return self._set_parameter(uuid, 'anonymous', anonymous)
-        
-    def add_monitor(self, host_info):
-        query = """INSERT INTO monitors
-        (uuid, 
-         hostname, 
-         ip, 
-         workers,
-         sage_version, 
-         os, 
-         kernel_version, 
-         cpus, 
-         cpu_speed, 
-         cpu_model, 
-         mem_total, 
-         mem_free)
-        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 
-        """
-        
-        uuid = host_info['uuid']
-        hostname = host_info['hostname']
-        ip = host_info['ip']
-        workers = host_info['workers']
-        sage_version = host_info['sage_version']
-        os = host_info['os']
-        kernel_version = host_info['kernel_version']
-        cpus = host_info['cpus']
-        cpu_speed = host_info['cpu_speed']
-        cpu_model = host_info['cpu_model']
-        mem_total = host_info['mem_total']
-        mem_free = host_info['mem_free']
-        
-        cur = self.con.cursor()
-        cur.execute(query, (uuid, hostname, ip, workers, sage_version, os, 
-                            kernel_version, cpus, cpu_speed, cpu_model,
-                            mem_total, mem_free))
-        self.con.commit()
-    
-    def get_monitor(self, uuid):
-        query = """SELECT uuid, hostname, ip, anonymous, sage_version, os FROM monitors 
-        WHERE uuid=?"""
-        cur = self.con.cursor()
-        cur.execute(query, (uuid,))
-        result = cur.fetchone()
-        if result is None:
-            return result
-        columns = [desc[0] for desc in cur.description]
-        monitor = dict(zip(columns, result))
-        for k, v in monitor.iteritems():
-            if k == 'anonymous':
-                monitor[k] = bool(v)
-                
-        return monitor
-
-    def get_monitor_list(self):
-        """
-        Returns a list of connected monitors.
-        
-        """
-        
-        query = """SELECT uuid, hostname, ip, anonymous, sage_version, os FROM monitors 
-        WHERE connected"""
-        cur = self.con.cursor()
-        cur.execute(query)
-        result = cur.fetchall()
-        columns = [desc[0] for desc in cur.description]
-        monitors = [dict(zip(columns, monitor)) for monitor in result]
-        for monitor in monitors:
-            for k, v in monitor.iteritems():
-                if k == 'anonymous':
-                    monitor[k] = bool(v)
-                    
-        return monitors
-        
-    def set_connected(self, uuid, connected=True):
-        """
-        Sets the connected status of a worker.
-        
-        Parameters:
-        uuid -- string
-        connected -- bool
-        
-        """
-        
-        cur = self.con.cursor()
-        if connected:
-            query = """UPDATE monitors SET connected=1, last_connection=?
-            WHERE uuid=?"""
-            cur.execute(query, (datetime.datetime.now(), uuid))
-        else:
-            query = """UPDATE monitors SET connected=0 WHERE uuid=?"""
-            cur.execute(query, (uuid,))
-            
-        self.con.commit()
-    
-    def set_busy(self, uuid, busy):
-        """
-        Sets whether or not a worker is doing a job.
-        
-        """
-        
-        if busy:
-            query = """UPDATE monitors SET busy=1 WHERE uuid=?"""
-        else:
-            query = """UPDATE monitors SET busy=0 WHERE uuid=?"""
-        
-        cur = self.con.cursor()
-        cur.execute(query, (uuid,))
-        self.con.commit()
-        
-    def get_worker_count(self, connected, busy):
-        """
-        Returns the number of workers.
-        
-        Parameters:
-        connected -- bool
-        busy -- bool
-        
-        """
-        
-        if connected and not busy:
-            query = """SELECT workers FROM monitors WHERE connected AND NOT busy"""
-        elif connected and busy:
-            query = """SELECT workers FROM monitors WHERE connected AND busy"""
-        elif connected:
-            query = """SELECT workers FROM monitors WHERE connected"""
-        else:
-            query = "SELECT workers FROM monitors WHERE NOT connected"
-        
-        cur = self.con.cursor()
-        cur.execute(query)
-        result = cur.fetchall()
-        
-        return sum(w[0] for w in result)
-
-    def get_cpu_speed(self, connected=True, busy=True):
-        """
-        Returns the aggregate cpu speed in Mhz.
-        
-        Parameters:
-        connected -- bool
-        
-        """
-        
-        if connected:
-            query = """SELECT cpu_speed, workers FROM monitors 
-            WHERE connected AND busy"""
-        else:
-            query = """SELECT cpu_speed, workers FROM monitors"""
-            
-        cur = self.con.cursor()
-        cur.execute(query)
-        
-        result = cur.fetchall()
-        
-        cpu_speed = sum([s[0]*s[1] for s in result])
-        
-        return cpu_speed
-    
-    def get_cpu_count(self, connected=True):
-        """
-        Returns the number of cpus that are available.
-        
-        Parameters:
-        connected -- bool
-        
-        """
-        
-        if connected:
-            query = """SELECT workers, cpus FROM monitors WHERE connected"""
-        else:
-            query = """SELECT workers, cpus FROM monitors"""
-        
-        cur = self.con.cursor()
-        cur.execute(query)
-        
-        result = cur.fetchall()
-        
-        cpu_count = sum(min(s[0:2]) for s in result)
-        
-        return cpu_count
Index: age/dsage/database/sql_functions.py
===================================================================
--- sage/dsage/database/sql_functions.py	(revision 3866)
+++ 	(revision )
@@ -1,61 +1,0 @@
-##############################################################################
-#                                                                     
-#  DSAGE: Distributed SAGE                     
-#                                                                             
-#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
-#                                                                            
-#  Distributed under the terms of the GNU General Public License (GPL)        
-#
-#    This code 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
-#    General Public License for more details.
-#
-#  The full text of the GPL is available at:
-#
-#                  http://www.gnu.org/licenses/
-#
-##############################################################################
-
-from twisted.python import log
-
-def table_exists(con, tablename):
-    """
-    Check if a given table exists.
-    If the below query is not None, then the table exists
-    
-    """
-    
-    query = """SELECT name FROM sqlite_master 
-    WHERE type = 'table' AND name = ?;
-    """
-    
-    cur = con.cursor()
-    cur.execute(query, (tablename,))
-    result = cur.fetchone()
-    return result
-    
-def create_table(con, tablename, query):
-    """
-    Creates a table given the connection.
-    
-    """
-
-    log.msg('Creating table %s...' % tablename)    
-    con.execute(query)
-
-def fields(cursor):
-    """
-    Given a DB API 2.0 cursor object that has been executed, returns
-    a dictionary that maps each field name to a column index, 0 and up.
-    
-    """
-    
-    results = {}
-    for column, desc in enumerate(cursor.description):
-        results[desc[0]] = column
-    
-    return results
-
-def add_trigger(con, trigger):
-    con.execute(trigger)
Index: age/dsage/database/tests/test_clientdb.py
===================================================================
--- sage/dsage/database/tests/test_clientdb.py	(revision 3866)
+++ 	(revision )
@@ -1,74 +1,0 @@
-##############################################################################
-#                                                                     
-#  DSAGE: Distributed SAGE                     
-#                                                                             
-#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
-#                                                                            
-#  Distributed under the terms of the GNU General Public License (GPL)        
-#
-#    This code 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
-#    General Public License for more details.
-#
-#  The full text of the GPL is available at:
-#
-#                  http://www.gnu.org/licenses/
-#
-##############################################################################
-
-import unittest
-
-import datetime
-
-from sage.dsage.database.clientdb import ClientDatabase
-
-class ClientDatabaseTestCase(unittest.TestCase):
-    """
-    Test cases for DSAGE's ClientDatabase
-    
-    """
-    
-    TEST_USERNAMES = ['yi', 'alex', 'dorian', 'robert', 'william', 'martin']
-    TEST_EMAILS = ['foo@bar.com', 'bar@foo.com', '1@2.com', '2@4.com', '5@6.com', '6@7.com' ]
-    TEST_KEYS = ['1', '2', '3', '4', '5', '6']
-    
-    def setUp(self):
-        self.clientdb = ClientDatabase(test=True)
-    
-    def tearDown(self):
-        query = """DELETE FROM clients"""
-        cur = self.clientdb.con.cursor()
-        cur.execute(query)
-        self.clientdb.con.commit()
-        self.clientdb._shutdown()
-
-    def testadd_user(self):
-        for user, key in zip(self.TEST_USERNAMES, self.TEST_KEYS):
-            self.clientdb.add_user(user, key)
-            self.assert_(self.clientdb.get_user(user) is not None)
-            
-    def testdel_user(self):
-        for user in self.TEST_USERNAMES:
-            self.clientdb.del_user(user)
-            self.assert_(self.clientdb.get_user(user) is None)
-    
-    def testset_enabled(self):
-        username = self.TEST_USERNAMES[0]
-        self.clientdb.add_user(username, self.TEST_KEYS[0])
-        self.clientdb.set_enabled(username, enabled=True)
-        self.assertEquals(self.clientdb.get_enabled(username), True)
-        self.clientdb.set_enabled(username, enabled=False)
-        self.assertEquals(self.clientdb.get_enabled(username), False)
-    
-    def testupdate_login_time(self):
-        username = self.TEST_USERNAMES[0]
-        self.clientdb.add_user(username, self.TEST_KEYS[0])
-        pre_login_time = self.clientdb.get_parameter(username, 'last_login')
-        self.assertEquals(pre_login_time, None)
-        self.clientdb.update_login_time(username)
-        post_login_time = self.clientdb.get_parameter(username, 'last_login')
-        self.assert_(datetime.datetime.now() > post_login_time)
-        
-if __name__ == '__main__':
-	unittest.main()
Index: sage/dsage/database/tests/test_job.py
===================================================================
--- sage/dsage/database/tests/test_job.py	(revision 3852)
+++ sage/dsage/database/tests/test_job.py	(revision 2944)
@@ -25,19 +25,22 @@
 class JobTestCase(unittest.TestCase):
    
-    def testcreate_job(self):
+    def testcreateJob(self):
         job = Job()
         self.assert_(isinstance(job, Job))
 
-        job = Job(id_=10, name='test', code='test', parent='test', 
-                  username='test', type_='test')
+        job = Job(id=10, name='test', file='test', parent='test', 
+                  author='test', type='test')
         self.assert_(isinstance(job, Job))
     
-    def testjob_id(self):
+    def testjobID(self):
         job = Job()
-        self.assertRaises(TypeError, job.job_id, 5)
+        self.assertRaises(TypeError, job.id, 5)
 
+    def testjobNum(self):
+        job = Job()
+        self.assertEquals(None, job.num)
     def testjobFile(self):
         job = Job()
-        self.assertRaises(TypeError, job.code, 1)
+        self.assertRaises(TypeError, job.file, 1)
 
     def testjobCreationTime(self):
@@ -51,8 +54,8 @@
         self.assertRaises(TypeError, job.finish_time, 'test')
 
-    def testjobUpdateTime(self):
+    def testjobUpdatedTime(self):
         job = Job()
-        self.assertEquals(job.update_time, None)
-        self.assertRaises(TypeError, job.update_time, 'test')
+        self.assertEquals(job.updated_time, None)
+        self.assertRaises(TypeError, job.updated_time, 'test')
 
     def testjobStatus(self):
Index: sage/dsage/database/tests/test_jobdb.py
===================================================================
--- sage/dsage/database/tests/test_jobdb.py	(revision 3866)
+++ sage/dsage/database/tests/test_jobdb.py	(revision 2944)
@@ -15,5 +15,4 @@
 #
 #                  http://www.gnu.org/licenses/
-#
 ############################################################################
 
@@ -23,6 +22,5 @@
 from glob import glob
 
-from sage.dsage.database.jobdb import JobDatabaseZODB, JobDatabaseSQLite
-from sage.dsage.database.jobdb import DatabasePruner
+from sage.dsage.database.jobdb import JobDatabaseZODB, DatabasePruner
 from sage.dsage.database.job import Job
 
@@ -31,7 +29,7 @@
         self.jobdb = JobDatabaseZODB(test=True)
         
-        jobs = self.create_jobs(10)
+        jobs = self.createJobs(10)
         for job in jobs:
-            self.jobdb.new_job(job)
+            self.jobdb.newJob(job)
 
     def tearDown(self):
@@ -41,125 +39,80 @@
             os.remove(file)
    
-    def testhas_job(self):
-        job = self.create_jobs(1)
-        job_id = self.jobdb.store_job(job[0])
-        self.assertEquals(self.jobdb.has_job(job_id), True)
-        self.assert_(self.jobdb.has_job('GLOBALS') > 0)
+    def testhasJob(self):
+        job = self.createJobs(1)
+        jobID = self.jobdb.storeJob(job[0])
+        self.assertEquals(self.jobdb.hasJob(jobID), True)
+        self.assert_(self.jobdb.hasJob('GLOBALS') > 0)
 
-    def testget_next_job_id(self):
+    def testgetJobID(self):
         """Attempt to increment Job ID by one. """
 
-        job_id = self.jobdb.get_next_job_id()
-        job_id1 = self.jobdb.get_next_job_id()
+        jobID = self.jobdb.getJobID()
+        jobID1 = self.jobdb.getJobID()
 
-        self.assert_(int(job_id[11:]) < int(job_id1[11:]))
+        self.assert_(int(jobID[11:]) < int(jobID1[11:]))
 
-    def testget_job(self):
-        job = self.jobdb.get_job()
+    def testgetJob(self):
+        job = self.jobdb.getJob()
         self.assert_(isinstance(job, Job) and job.status != 'completed')
 
-    def testremove_job(self):
-        self.assertRaises(KeyError, self.jobdb.remove_job, 'not_a_job_id')
+    def testremoveJob(self):
+        self.assertRaises(KeyError, self.jobdb.removeJob, 'not_a_job_id')
 
-        job = self.jobdb.get_job()
+        job = self.jobdb.getJob()
         self.assertEquals(type(job), Job)
-        job_id = job.job_id
-        self.assertEquals(self.jobdb.remove_job(job_id), job_id)
-        self.assertRaises(KeyError, self.jobdb.remove_job, job_id)
+        job_id = job.id
+        self.assertEquals(self.jobdb.removeJob(job_id), job_id)
+        self.assertRaises(KeyError, self.jobdb.removeJob, job_id)
 
-    def teststore_job(self):
-        jobs = self.create_jobs(10)
+    def teststoreJob(self):
+        jobs = self.createJobs(10)
         for job in jobs:
-            job_id = self.jobdb.new_job(job)
-            self.assertEquals(job, self.jobdb.get_job_by_id(job_id))
-            self.assert_(self.jobdb.get_job_by_id(job_id).update_time <
+            job_id = self.jobdb.newJob(job)
+            self.assertEquals(job, self.jobdb.getJobByID(job_id))
+            self.assert_(self.jobdb.getJobByID(job_id).updated_time <
                          datetime.datetime.now())
 
-    def testget_jobs_by_username(self):
-        jobs = self.jobdb.get_jobs_by_username('Yi Qiang', True)
+    def testgetJobsByAuthor(self):
+        jobs = self.jobdb.getJobsByAuthor('Yi Qiang', True)
         self.assert_(len(jobs) == 0)
 
-        jobs = self.jobdb.get_jobs_by_username('Yi Qiang', False, 'unittest')
+        jobs = self.jobdb.getJobsByAuthor('Yi Qiang', False, 'unittest')
         self.assert_(len(jobs) > 0)
 
-    def testget_active_jobs(self):
-        jobs = self.jobdb.get_active_jobs()
+    def testgetActiveJobs(self):
+        jobs = self.jobdb.getActiveJobs()
         self.assert_(len(jobs) == 0)
         
-        jobs = self.jobdb.get_jobs_list()
+        jobs = self.jobdb.getJobsList()
         for job in jobs:
             job.status = 'processing'
-            self.jobdb.store_job(job)
+            self.jobdb.storeJob(job)
 
-        jobs = self.jobdb.get_active_jobs()
+        jobs = self.jobdb.getActiveJobs()
         self.assert_(len(jobs) == 10)
 
-    def testget_jobs_list(self):
-        jobs = self.jobdb.get_jobs_list()
-        self.assertEquals(len(jobs), 10)
+    def testgetJobsList(self):
+        jobs = self.jobdb.getJobsList()
+    
+        for i in xrange(len(jobs)-1):
+            self.assert_(jobs[i].num < jobs[i+1].num)
 
-    def create_jobs(self, n):
+    def createJobs(self, n):
         """This method creates n jobs. """
 
         jobs = []
         for i in range(n):
-            jobs.append(Job(name='unittest', username='Yi Qiang'))
+            jobs.append(Job(name='unittest', author='Yi Qiang'))
 
         return jobs
 
-class JobDatabaseSQLiteTestCase(unittest.TestCase):
-    """
-    Unit tests for the SQLite based JobDatabase go here.
-    
-    """
-    
-    def setUp(self):
-        self.jobdb = JobDatabaseSQLite(test=True)
-    
-    def tearDown(self):
-        query = """DELETE FROM jobs"""
-        cur = self.jobdb.con.cursor()
-        cur.execute(query)
-        self.jobdb._shutdown()
-    
-    def testget_job(self):
-        job = Job()
-        job.status = 'new'
-        job.killed = False
-        jdict = self.jobdb.store_job(job.reduce())
-        self.assertEquals(jdict['job_id'], self.jobdb.get_job()['job_id'])
-        
-    def teststore_job(self):
-        job = Job()
-        self.assert_(isinstance(self.jobdb.store_job(job.reduce()), dict))
-        
-    def testget_job_by_id(self):
-        job = Job()
-        jdict = self.jobdb.store_job(job.reduce())
-        self.assert_(self.jobdb.get_job_by_id(jdict['job_id']) is not None)
-    
-    def testhas_job(self):
-        job = Job()
-        jdict = self.jobdb.store_job(job.reduce())
-        self.assertEquals(self.jobdb.has_job(jdict['job_id']), True)
-    
-    def testcreate_jdict(self):
-        job = Job()
-        jdict = self.jobdb.store_job(job.reduce())
-        self.assert_(isinstance(jdict, dict))
-    
-    def testget_killed_jobs_list(self):
-        job = Job()
-        jdict = self.jobdb.store_job(job.reduce())
-        self.jobdb.set_killed(jdict['job_id'], killed=True)
-        self.assertEquals(len(self.jobdb.get_killed_jobs_list()), 1)
-        
 class DatabasePrunerTestCase(unittest.TestCase):
     def setUp(self):
         self.jobdb = JobDatabaseZODB(test=True)
         self.pruner = DatabasePruner(self.jobdb) 
-        jobs = self.create_jobs(10)
+        jobs = self.createJobs(10)
         for job in jobs:
-            self.jobdb.new_job(job)
+            self.jobdb.newJob(job)
 
 
@@ -170,33 +123,33 @@
             os.remove(file)
 
-    def testclean_old_jobs(self):
-        jobs = self.jobdb.get_jobs_list()
+    def testcleanOldJobs(self):
+        jobs = self.jobdb.getJobsList()
         for job in jobs:
-            job.update_time -= datetime.timedelta(10)
-            # directly accessing the database because store_job
-            # automatically updates the update_time
-            self.jobdb.jobdb[job.job_id] = job
+            job.updated_time -= datetime.timedelta(10)
+            # directly accessing the database because storeJob
+            # automatically updates the updated_time
+            self.jobdb.jobdb[job.id] = job
 
-        self.pruner.clean_old_jobs()
+        self.pruner.cleanOldJobs()
 
-        jobs = self.jobdb.get_jobs_list()
+        jobs = self.jobdb.getJobsList()
         self.assertEquals(len(jobs), 0)
 
-    def testclean_failed_jobs(self):
-        jobs = self.jobdb.get_jobs_list()
+    def testcleanFailedJobs(self):
+        jobs = self.jobdb.getJobsList()
         for job in jobs:
             job.failures += 20
-            self.jobdb.store_job(job)
+            self.jobdb.storeJob(job)
 
-        self.pruner.clean_failed_jobs()
-        jobs = self.jobdb.get_jobs_list()
+        self.pruner.cleanFailedJobs()
+        jobs = self.jobdb.getJobsList()
         self.assertEquals(len(jobs), 0)
 
-    def create_jobs(self, n):
+    def createJobs(self, n):
         """This method creates n jobs. """
 
         jobs = []
         for i in range(n):
-            jobs.append(Job(name='unittest', username='Yi Qiang'))
+            jobs.append(Job(name='unittest', author='Yi Qiang'))
 
         return jobs
Index: sage/dsage/dist_functions/all.py
===================================================================
--- sage/dsage/dist_functions/all.py	(revision 3837)
+++ sage/dsage/dist_functions/all.py	(revision 2942)
@@ -1,20 +1,2 @@
-##############################################################################
-#                                                                     
-#  DSAGE: Distributed SAGE                     
-#                                                                             
-#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
-#                                                                            
-#  Distributed under the terms of the GNU General Public License (GPL)        
-#
-#    This code 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
-#    General Public License for more details.
-#
-#  The full text of the GPL is available at:
-#
-#                  http://www.gnu.org/licenses/
-#
-##############################################################################
 from dist_function import DistributedFunction, DistributedFunctionTest
 from dist_factor import DistributedFactor
Index: sage/dsage/dist_functions/dist_factor.py
===================================================================
--- sage/dsage/dist_functions/dist_factor.py	(revision 3874)
+++ sage/dsage/dist_functions/dist_factor.py	(revision 3016)
@@ -6,5 +6,5 @@
 
 class DistributedFactor(DistributedFunction):
-    """
+    r"""
     DistributedFactor uses ECM and QSIEVE to find factors of numbers.
        
@@ -17,7 +17,7 @@
     """
     
-    def __init__(self, DSage, n, concurrent=10, verbosity=0, trial_division_limit=10000,
-                 name='DistributedFactor'):
-        """
+    def __init__(self, DSage, n, concurrent=10, verbosity=0,
+                 trial_division_limit=10000, name='DistributedFactor'):
+        r"""
         Parameters:
             DSage -- an instance of a dsage connection
@@ -36,5 +36,4 @@
         self.n = n
         self.prime_factors = []
-        self.composite_factors = []
         self.cur_B1 = 2000
         self.curve_count = 50
@@ -42,4 +41,5 @@
         self.verbosity = verbosity
         self.name = name
+        
         # Trial division first to peel off some factors
         for d in prime_range(2, trial_division_limit):
@@ -49,9 +49,6 @@
         if n == 1:
             self.done = True
-        elif is_prime(n): # The last value might be prime
-            self.done = True
-            self.prime_factors.append(n)
         else:
-            self.composite_factors.append(n)
+            self.composite_factors = [n]
             self.outstanding_jobs = [self.qsieve_job()]
             for i in range(concurrent-1):
@@ -65,5 +62,5 @@
         if n < 10**40:
             return self.ecm_job()
-        job = Job(code="""
+        job = Job(file="""
 n = %s
 if is_prime(n):
@@ -71,5 +68,7 @@
 else:
     v, t = qsieve(n)
-    DSAGE_RESULT = [v, [0]*len(v), {}, 'qsieve']
+    result = [v, [0]*len(v), {}, 'qsieve']
+    save(result, 'result')
+    DSAGE_RESULT = 'result.sobj'
 """ % n, name='qsieve')
         job.n = int(n) # otherwise cPickle will crash
@@ -84,11 +83,13 @@
         n = self.composite_factors[self.i % len(self.composite_factors)]
         rate_multiplier = float(self.concurrent / len(self.composite_factors))
-        job = Job(code="""
+        job = Job(file="""
 n = %s
 if is_prime(n):
-    DSAGE_RESULT = [[n], [True], {}, 'primality']
+    result = [[n], [True], {}, 'primality']
 else:
     e = ECM()
-    DSAGE_RESULT = [e.find_factor(n, B1=%s, c=%s, I=%s), e.primality, e.last_params, 'ecm']
+    result = [e.find_factor(n, B1=%s, c=%s, I=%s), e.primality, e.last_params, 'ecm']
+save(result, 'result')
+DSAGE_RESULT = 'result.sobj'
 
 """ % (n, self.cur_B1, self.curve_count, rate_multiplier), name='ecm' )
@@ -98,5 +99,5 @@
     
     def process_result(self, job):
-        """
+        r"""
         For each factor m of n found by the worker, record them by
             1) Dividing each element x of composite_factors by gcd(x,m)
@@ -107,5 +108,5 @@
         
         """
-
+        
         if prod(self.prime_factors) == self.n:
             self.done = True
@@ -120,8 +121,6 @@
         try:
             factors, primality, params, algorithm = result
-        except Exception, msg:
+        except:
             print 'Error in processing result.'
-            print result
-            print msg
             return
         try:
@@ -136,5 +135,6 @@
                 self.prime_factors.append("BAD FACTORS")
             # switch the order of indices
-            result = [(result[0][i], result[1][i]) for i in range(len(result[0]))]
+            result = [(result[0][i],
+                       result[1][i]) for i in range(len(result[0]))]
             # Only works for square-free numbers
             for r, is_prime_factor in result:
@@ -176,5 +176,4 @@
         else:
             self.qsieve_count = 0
-            to_be_removed_jobs = []
             for wrapped_job in self.waiting_jobs:
                 if wrapped_job.algorithm == 'qsieve':
@@ -186,13 +185,10 @@
                         else:
                             wrapped_job.async_kill()
-                        to_be_removed_jobs.append(wrapped_job)
+                        self.waiting_jobs.remove(wrapped_job)
                     else:
                         self.qsieve_count += 1
-            for job in to_be_removed_jobs:
-                self.waiting_jobs.remove(job)
+            # Need to use async versions of submitting the jobs because 
+            # this method is called from within the reactor thread
             if self.qsieve_count == 0:
                 self.submit_job(self.qsieve_job(), self.name, async=True)
             self.submit_job(self.ecm_job(), self.name, async=True)
-            
-        self.prime_factors.sort()
-        self.composite_factors.sort()
Index: sage/dsage/dist_functions/dist_function.py
===================================================================
--- sage/dsage/dist_functions/dist_function.py	(revision 3905)
+++ sage/dsage/dist_functions/dist_function.py	(revision 3017)
@@ -15,17 +15,20 @@
 #
 #                  http://www.gnu.org/licenses/
-#
 ############################################################################
 
 import datetime
+import copy
 import cPickle
 import zlib
 
+from twisted.internet import reactor, task
+from twisted.spread import pb
+
 from sage.dsage.database.job import Job
-from sage.dsage.interface.dsage_interface import JobWrapper, BlockingJobWrapper
-from sage.dsage.twisted.misc import blocking_call_from_thread
+from sage.dsage.interface.dsage_interface import JobWrapper, blockingJobWrapper
+from sage.dsage.twisted.misc import blockingCallFromThread
 
 class DistributedFunction(object):
-    """
+    r"""
     Parent class for all classes that wish to use Distributed SAGE.
 
@@ -45,12 +48,11 @@
         self.name = None
         self.job_files = []
+        # self.checker_task = None
         self._done = False
 
     def __getstate__(self):
-        import copy
-        d = copy.copy(self.__dict__)
+        d = copy(self.__dict__)
         d['DSage'] = None
         d['checker_task'] = None
-        
         return d
 
@@ -72,6 +74,6 @@
 
     def save(self, filename=None, compress=True):
-        """
-        Saves your distributed job to disk.
+        r"""
+        Saves your distributed job to a sobj.
         
         """
@@ -87,30 +89,10 @@
         f.write(s)
         f.close()
-        
         return filename
 
-    def stop(self, verbose=True):
-        """
-        Ends the current DistributedFunction, kills all waiting jobs.
-        
-        """
-        
-        for job in self.waiting_jobs:
-            job.kill()
-            
-        self.done = True
-        
-        if verbose:
-            print 'All waiting jobs have been killed. This job is no more.'
-        
     def restore(self, dsage):
-        """
-        Reloads a distributed job from disk.
-        
-        """
-        
-        from twisted.internet import reactor, task
         if dsage.remoteobj is None:
             # XXX This is a hack because dsage.remoteobj is not set yet
+            from twisted.internet import reactor
             reactor.callLater(1.0, self.restore, dsage)
             return
@@ -120,71 +102,47 @@
         if not len(self.outstanding_jobs) == 0:
             self.submit_jobs(self.name)
-            
         self.checker_task = task.LoopingCall(self.check_results)
-        reactor.callFromThread(self.checker_task.start, 1.0, now=True)
+        self.checker_task.start(2.0, now=True)
 
-    def submit_job(self, job, job_name='job', async=True):
-        """
-        Submits a job to the server.
-        
-        """
-        
-        job.username = self.DSage.username
+    def submit_job(self, job, job_name='job', async=False):
         if async:
             if isinstance(job, Job):
-                self.waiting_jobs.append(self.DSage.send_job(job, async=True))
+                self.waiting_jobs.append(self.DSage.send_job(job, 
+                                                             async=True))
             else:
-                self.waiting_jobs.append(self.DSage.eval(job, job_name=job_name, async=True))
+                self.waiting_jobs.append(self.DSage.eval(job, 
+                                                         job_name=job_name,
+                                                         async=True))
         else:
             if isinstance(job, Job):
-                self.waiting_jobs.append(self.DSage.send_job(job, async=False))
+                self.waiting_jobs.append(self.DSage.send_job(job))
             else:
-                self.waiting_jobs.append(self.DSage.eval(job, job_name=job_name))
+                self.waiting_jobs.append(self.DSage.eval(job,
+                                                         job_name=job_name))
     
-    def submit_jobs(self, job_name='job', async=True):
-        """
-        Repeatedly calls submit_job until we have no more jobs in outstanding_jobs
-        
-        """
-        
+    def submit_jobs(self, job_name='job', async=False):
         for job in self.outstanding_jobs:
-            try:              
-               self.submit_job(job, job_name, async)
-            except Exception, msg:
-               print msg
+           self.submit_job(job, job_name, async)
         self.outstanding_jobs = []
 
     def start(self):
-        from twisted.internet import reactor, task
-        if self.DSage is None:
-            print 'Error: Not connected to a DSage server.'
-            return
         self.start_time = datetime.datetime.now()
         reactor.callFromThread(self.submit_jobs, self.name, async=True)
-        self.checker_task = blocking_call_from_thread(task.LoopingCall, self.check_results)
-        reactor.callFromThread(self.checker_task.start, 1.0, now=True)
-    
-    def process_result(self):
-        """
-        Any class subclassing DistributedFunction should implement this method.
-        
-        """
-        
-        pass
-        
+        self.checker_task = blockingCallFromThread(task.LoopingCall,
+                                                   self.check_results)
+        reactor.callFromThread(self.checker_task.start, 
+                               1.0, now=True)
     def check_results(self):
-        from twisted.internet import reactor
-        from twisted.spread import pb
         for wrapped_job in self.waiting_jobs:
             if isinstance(wrapped_job, JobWrapper):
                 try:
-                    wrapped_job.get_job()
+                    wrapped_job.getJob()
                 except pb.DeadReferenceError:
-                    print 'Disconnected from the server, stopping checker_task.'
-                    if self.checker_task.running:
-                        reactor.callFromThread(self.checker_task.stop)
+                    print 'Got pb.DeadReferenceError.'
+                    print 'This will be handled in the future.'
+                    reactor.callFromThread(self.checker_task.stop)
                     break
-            elif isinstance(wrapped_job, BlockingJobWrapper):
-                wrapped_job.async_get_job()
+            else:
+                wrapped_job.async_getJob()
             if wrapped_job.status == 'completed': 
                 self.waiting_jobs.remove(wrapped_job)
@@ -192,20 +150,16 @@
                 self.processed_jobs.append(wrapped_job)
         if self.done:
+            # kill the jobs in the waiting queue
             for wrapped_job in self.waiting_jobs:
                 if isinstance(wrapped_job, JobWrapper):
                     wrapped_job.kill()
-                elif isinstance(wrapped_job, BlockingJobWrapper):
+                else:
                     wrapped_job.async_kill()
             self.waiting_jobs = []
-            if self.checker_task.running:
-                reactor.callFromThread(self.checker_task.stop)
+            reactor.callFromThread(self.checker_task.stop)
+
+        self.done = len(self.waiting_jobs) == 0
         
 class DistributedFunctionTest(DistributedFunction):
-    """
-    This is a very simple DistributedFunction.  
-    Only for educational purposes.
-    
-    """
-    
     def __init__(self, DSage, n, name='DistributedFunctionTest'):
         DistributedFunction.__init__(self, DSage)
@@ -214,8 +168,6 @@
         self.result = 0
         self.results = []
-        self.code = """DSAGE_RESULT=%s"""
-        self.outstanding_jobs = [Job(code=self.code % i, username='yqiang') for i in range(1, n+1)]
-        
+        self.outstanding_jobs = ["print %s"%i for i in range(1,n+1)]
+
     def process_result(self, job):
-        self.done = len(self.waiting_jobs) == 0
-        self.result += (job.result)
+        self.result += int(job.output)
Index: sage/dsage/dist_functions/dist_povray.py
===================================================================
--- sage/dsage/dist_functions/dist_povray.py	(revision 3866)
+++ sage/dsage/dist_functions/dist_povray.py	(revision 3018)
@@ -5,5 +5,5 @@
 
 class DistributedPOVRay(DistributedFunction):
-    """
+    r"""
     DistributedPOVRay distributes rendering of a .pov file.
     
@@ -21,4 +21,7 @@
         which is the combination of all the rendered parts.
 
+    AUTHOR:
+        Yi Qiang 
+        
     """
 
@@ -73,5 +76,5 @@
         self.job_files.append(job_file)
 
-        job = Job(code=job_file, name='%s_%04d.ppm' % (self.name, self.n))
+        job = Job(file=job_file, name='%s_%04d.ppm' % (self.name, self.n))
         
         for file_ in self.files:
Index: age/dsage/doc/dsage.tex
===================================================================
--- sage/dsage/doc/dsage.tex	(revision 3746)
+++ 	(revision )
@@ -1,28 +1,0 @@
-%
-%  Distributed SAGE
-%
-%  Created by Yi Qiang on 2007-02-20.
-%  Copyright (c) 2007 Yi Qiang. All rights reserved.
-%
-\documentclass[]{howto}
-\title{Distributed SAGE HOWTO}
-\author{
-    Yi Qiang\\
-    yqiang@gmail.com
-}
-\release{1.0}
-\date{2007-02-22}
-
-\begin{document}
-
-\maketitle
-
-\begin{abstract}
-    This document will demonstrate how to use Distributed SAGE.
-\end{abstract}
-
-\section{Introduction}
-\sectionauthor{Yi Qiang}{yqiang@gmail.com}
-            
-
-\end{document}
Index: sage/dsage/dsage.py
===================================================================
--- sage/dsage/dsage.py	(revision 3914)
+++ sage/dsage/dsage.py	(revision 3025)
@@ -8,100 +8,70 @@
 import os
 
-import sage.interfaces.cleaner
-from sage.misc.all import DOT_SAGE
-import pexpect
-
-## def spawn(cmd, logfile=None, verbose=True):
-##     pid = os.fork()
-##     if pid != 0:
-##         sage.interfaces.cleaner.cleaner(pid)
-##         if verbose:
-##             print "Started %s (pid = %s, logfile = '%s')"%(cmd, pid, logfile)
-##         return pid
-##     if pid == 0:
-##         if not logfile is None:
-##             cmd += ' 2>&1 > ' + logfile
-##         os.system(cmd)
-
-## def start_process(typ, hostname, address, port):
-##     cmd = 'dsage_%s.py &'%typ
-##     os.system(cmd)
-##     dir = '%s/dsage/'%os.environ['DOT_SAGE']
-##     pid_file = '%s/server-hostname-address-port.pid'%dir
-##     while True:
-##         try:
-##             if os.path.exists(pid_file):
-##                 return int(open(pid_file).read())
-##         except Exception, msg:
-##             print msg
-       
-
 class DistributedSage(object):
     r"""
-    DistributedSage allows you to do distributed computing using SAGE.
+    DistributedSage allows you to do distributed computing in SAGE.
 
-    To get up and running quickly, run dsage.setup() to run the 
-    configuration utility.
-
-    Note that configuration files will be stored in the
-    directory \code{\$DOT\_SAGE/dsage}.
+    To get up and running quickly, run dsage.setup() to run the configuration
+    utility.
+    Note that configuration files will be stored in DOT_SAGE/dsage
 
     There are three distinct parts of Distributed SAGE:
         Server
             Launch the server with dsage.server()
-            
         Worker
             Launch the worker with dsage.worker()
-            
         Client
             Create the DSage object like this:
                 d = DSage()
     
-    EXAMPLES:
-    This starts a server instance on localhost:
-    
+    Examples:
+        This starts a server instance on localhost
+
         sage: dsage.server()
+        This is currently blocking
 
-    The dsage server is currently blocking by default.
-
-    Open another sage instance and type:
+        Open another sage instance and type
 
         sage: dsage.worker() 
 
-    This starts a worker connecting the localhost.
+        This starts a worker connecting the localhost
 
-    Open yet another terminal and type:
+        Open yet another terminal and type:
+
         sage: D = DSage()
 
-    This creates a connection to the remote server.  To do a simple
-    evaluation, type:
+        This creates a connection to the remote server.  To do a simple
+        evaluation, type:
+
         sage: job1 = D('2+2')
 
-    This sends the job '2+2' to a worker and you can view the 
-    result by typing:
+        This sends the job 'print 2+2' to a worker and you can view the 
+        result by typing:
 
         sage: print job1
 
-    This is the most basic way of interacting with dsage. To do more
-    complicated tasks, you should look at the DistributedFunction
-    class.  For example, to do distributed integer factorization with
-    ECM, type this:
+        This is the most basic way of interacting with dsage. To do more 
+        complicated tasks, you should look at the DistributedFunction class. 
+        For example, to do distributed integer factorization with ECM, type 
+        this:
 
         sage: f = DistributedFactor(P, number, name='my_factor')
         sage: f.start()
 
-    To check the result, do
+        To check the result, do
 
         sage: print f.result 
 
-    To check if it is done, do
+        To check if it is done, do
 
         sage: print f.done
 
     Customization:
-    
-        To customize how the worker, server, or client behaves, you
-        can look for their respective conf files in DOT_SAGE/dsage.
-        The configuration file should be self explanatory.
+        To customize how the worker, server, or client behaves, you can look
+        for their respective conf files in DOT_SAGE/dsage.  The configuration
+        file should be self explanatory.
+
+    TODO: 
+
     """
     def __init__(self):
@@ -112,93 +82,55 @@
         self.worker(blocking=False)
         from sage.dsage.interface.dsage_interface import BlockingDSage as DSage
-        
         return DSage()
         
-##     def server(self, blocking=True, logfile=None):
-##         r"""
-##         Run the Distributed SAGE server.
+    def server(self, blocking=True):
+        r"""
+        This is the server of Distributed SAGE
         
-##         Doing \code{dsage.server()} will spawn a server process which
-##         listens by default on port 8081.
+        Doing dsage.server() will spawn a server process which listens by
+        default on ports 8081 and 8082. 
 
-##         INPUT:
-##             blocking -- boolean (default: True) -- if False the dsage
-##                         server will run and you'll still be able to
-##                         enter commands at the command prompt (though
-##                         logging will make this hard).
-##             logfile  -- only used if blocking=True; the default is
-##                         to log to $DOT_SAGE/dsage/server.log
-##         """
-##         cmd = 'dsage_server.py'
-##         if not blocking:
-##             if logfile is None:
-##                 logfile = '%s/dsage/server.log'%DOT_SAGE
-##             spawn(cmd, logfile)
-##         else:
-##             os.system(cmd)
+        """
 
-    def server(self):
+        cmd = 'dsage_server.py'
+        if not blocking:
+            cmd += '&'
+        os.system(cmd)
+
+    def worker(self, server=None, port=None, blocking=True):
         r"""
-        Run the Distributed SAGE server.
+        This is the worker of Distributed SAGE
+
+        Typing sage.worker() will launch a worker which by default connects to
+        localhost on port 8082 to fetch jobs.
         
-        Doing \code{dsage.server()} will spawn a server process which
-        listens by default on port 8081.
+        Parameters:
+        hostname -- the server you want to connect to
+        port -- the port that the server listens on for workers.
+
         """
-        cmd = 'dsage_server.py'
+
+        cmd = 'dsage_worker.py'
+        if isinstance(server, str):
+            cmd += ' %s' % server
+        if isinstance(port, int):
+            cmd += ' %s' % port
+        
+        if not blocking:
+            cmd += '&'
+    
         os.system(cmd)
-            
 
-##     def worker(self, server=None, port=None, blocking=True, logfile=None):
-##         r"""
-##         Run the Distributed SAGE worker. 
-
-##         Typing \code{sage.worker()} will launch a worker which by
-##         default connects to localhost on port 8081 to fetch jobs.
-        
-##         INPUT:
-
-##             server -- (string, default: None) the server you want to
-##                       connect to if None, connects to the server
-##                       specified in .sage/dsage/worker.conf
-##             port -- (integer, default: None) the port that the server
-##                       listens on for workers.
-##             blocking -- (bool, default: True) whether or not to make a
-##                         blocking connection.
-##             logfile -- only used if blocking=True; the default is
-##                        to log to $DOT_SAGE/dsage/worker.log
-##         """
-##         cmd = 'dsage_worker.py'
-##         if blocking:
-##             cmd += ' %s' % server
-##             cmd += ' %s' % port
-##             os.system(cmd)
-##         else:
-##             if not server is None or not port is None:
-##                 args = [str(server), str(port)]
-##             else:
-##                 args = []
-##             if logfile is None:
-##                 logfile = '%s/dsage/worker.log'%DOT_SAGE
-##             spawn(cmd + ' '.join(args), logfile)
-
-    def worker(self, server=None, port=None):
-        r"""
-        Run the Distributed SAGE worker. 
-
-        Typing \code{sage.worker()} will launch a worker which by
-        default connects to localhost on port 8081 to fetch jobs.
-        
-        INPUT:
-
-            server -- (string, default: None) the server you want to
-                      connect to if None, connects to the server
-                      specified in .sage/dsage/worker.conf
-            port -- (integer, default: None) the port that the server
-                      listens on for workers.
-        """
-        cmd = 'dsage_worker.py'
-        cmd += ' %s' % server
-        cmd += ' %s' % port
-        os.system(cmd)
+    # This is completely outdated now, only kept for historical reference
+    # def console(self):
+    #     r"""
+    #     This is the IPython console that allows you submit and view jobs.
+    # 
+    #     Simply type dsage.console() to launch it.  It is a special ipython
+    #     console because it has a twisted thread running in the background.  
+    #     """
+    #     # this is overwritten below.
+    #     cmd = 'dsage_console.py'
+    #     os.system(cmd)
 
     def setup(self):
@@ -206,9 +138,9 @@
         This is the setup utility which helps you configure dsage.
 
-        Type \code{dsage.setup()} to run the configuration for the server,
-        worker and client.  Alternatively, if you want to run the
-        configuration for just one parts, you can launch
-        \code{dsage.setup_server()}, \code{dsage.setup\_worker()}
-        or \code{dsage.setup()}.
+        Type dsage.setup() to run the configuration for the server, worker and
+        client.  Alternatively, if you want to run the configuration for just
+        one parts, you can launch dsage.setup_server(), dsage.setup_worker() or
+        dsage.setup() client
+
         """
         cmd = 'dsage_setup.py'
@@ -216,21 +148,24 @@
     
     def setup_server(self):
-        """
+        r"""
         This method runs the configuration utility for the server.
         """
+
         cmd = 'dsage_setup.py server'
         os.system(cmd)
 
     def setup_worker(self):
-        """
+        r"""
         This method runs the configuration utility for the worker.
         """
+
         cmd = 'dsage_setup.py worker'
         os.system(cmd)
 
     def setup_client(self):
-        """
+        r"""
         This method runs the configuration utility for the client.
         """
+
         cmd = 'dsage_setup.py client'
         os.system(cmd)
Index: sage/dsage/errors/exceptions.py
===================================================================
--- sage/dsage/errors/exceptions.py	(revision 3866)
+++ sage/dsage/errors/exceptions.py	(revision 2885)
@@ -54,13 +54,2 @@
 class BadKeyException(pb.Error):
     pass
-
-class AuthenticationError(pb.Error):
-    """
-    Return this when credential checking has failed.
-    
-    """
-    
-    def __init__(self, value, data=None):
-        Exception.__init__(self, value, data)
-        self.value = value
-        self.data = data
Index: sage/dsage/interface/dsage_interface.py
===================================================================
--- sage/dsage/interface/dsage_interface.py	(revision 3903)
+++ sage/dsage/interface/dsage_interface.py	(revision 3025)
@@ -15,9 +15,11 @@
 #
 #                  http://www.gnu.org/licenses/
-#
 ############################################################################
 
+import sys
 import os
+import random
 import glob
+import ConfigParser
 import copy
 import cPickle
@@ -26,16 +28,20 @@
 import time
 
-from sage.dsage.database.job import Job, expand_job
-from sage.dsage.twisted.misc import blocking_call_from_thread
-from sage.dsage.misc.config import get_conf
+from twisted.spread import pb
+from twisted.internet import reactor, defer, error, task
+from twisted.cred import credentials
+from twisted.conch.ssh import keys
+
+from sage.dsage.database.job import Job
+from sage.dsage.twisted.pb import ClientPBClientFactory
+from sage.dsage.twisted.misc import blockingCallFromThread
+from sage.dsage.errors.exceptions import NoJobException, NotConnectedException
 
 class DSageThread(threading.Thread):
     def run(self):
-        from twisted.internet import reactor
-        if not reactor.running:
-            reactor.run(installSignalHandlers=0)
+        reactor.run(installSignalHandlers=False)
 
 class DSage(object):
-    """
+    r"""
     This object represents a connection to the distributed SAGE server.
     """
@@ -43,45 +49,25 @@
     def __init__(self, server=None, port=8081, username=None, 
                  pubkey_file=None, privkey_file=None):
-        """
-        Parameters:
-        server -- str
-        port -- int
-        username -- str
-        pubkey_file -- str (Default: None)
-        privkey_file -- str (Default: None)
-        
-        """
-        
-        from twisted.cred import credentials
-        from twisted.conch.ssh import keys
-        from twisted.spread import banana
-        banana.SIZE_LIMIT = 100*1024*1024 # 100 MegaBytes
-        conf = get_conf(type='client')
+
+        # We will read the values in from the conf file first and let the
+        # user override the values stored in the conf file by keyword
+        # parameters
+    
+        self._getconf()
         
         if server is None:
-            self.server = self.conf['server']
+            self.server = SERVER
         else:
             self.server = server
-        if port is None:
-            self.port = self.conf['port']
-        else:
-            self.port = port
-        if username is None:
-            self.username = self.conf['username']
-        else:
-            self.username = username
-        if pubkey_file is None:
-            self.pubkey_file = self.conf['pubkey_file']
-        else:
-            self.pubkey_file = pubkey_file
-        if privkey_file is None:
-            self.privkey_file = self.conf['privkey_file']
-        else:
-            self.privkey_file = privkey_file
-        
-        self.ssl = int(self.conf['ssl'])
-        self.log_level = int(conf['log_level'])
+            
+        self.port = PORT
+        self.username = USERNAME
+        self.pubkey_file = PUBKEY_FILE
+        self.privkey_file = PRIVKEY_FILE
+
         self.remoteobj = None
         self.result = None
+
+        passphrase = self._getpassphrase()
         
         # public key authentication information
@@ -89,5 +75,6 @@
         # try getting the private key object without a passphrase first
         try:
-            self.priv_key = keys.getPrivateKeyObject(filename=self.privkey_file)
+            self.priv_key = keys.getPrivateKeyObject(
+                                filename=self.privkey_file)
         except keys.BadKeyError:
             passphrase = self._getpassphrase()
@@ -98,5 +85,5 @@
         self.alg_name = 'rsa'
         self.blob = keys.makePublicKeyBlob(self.pub_key)
-        self.data = self.conf['data']
+        self.data = DATA
         self.signature = keys.signData(self.priv_key, self.data)
         self.creds = credentials.SSHPrivateKey(self.username,
@@ -110,16 +97,15 @@
         self.connect()
 
-    def __repr__(self):
-        return self.__str__()
-        
     def __str__(self):
         self.check_connected()
-        self.info_str = 'Connected to: %s:%s' % (self.server, self.port)
+        self.info_str = 'Connected to: ' \
+                    + self.server + ':' + str(self.port)
         return self.info_str + '\r'
 
     def __call__(self, cmd, globals_=None, job_name=None):
         cmd = ['ans = %s\n' % (cmd),
-               'print ans\n',
-               "DSAGE_RESULT = ans\n"]
+               'print ans\n'
+               "save(ans, 'ans')\n"
+               "DSAGE_RESULT = 'ans.sobj'\n"]
                
         return self.eval(''.join(cmd), globals_=globals_, job_name=job_name)
@@ -129,5 +115,29 @@
         d['remoteobj'] = None
         return d
-        
+
+    def _getconf(self):
+        # randomly generated string we will use to sign
+        self.DATA =  ''.join([chr(i) for i in [random.randint(65, 123) for n in
+                        range(500)]])
+        self.DSAGE_DIR = os.path.join(os.getenv('DOT_SAGE'), 'dsage')
+        # Begin reading configuration
+        try:
+            conf_file = os.path.join(self.DSAGE_DIR, 'client.conf')
+            config = ConfigParser.ConfigParser()
+            config.read(conf_file)
+
+            self.LOG_FILE = config.get('log', 'log_file')
+            self.LOG_LEVEL = config.getint('log', 'log_level')
+            self.SSL = config.getint('ssl', 'ssl')
+            self.USERNAME = config.get('auth', 'username')
+            self.PRIVKEY_FILE = os.path.expanduser(config.get('auth',
+                                                              'privkey_file'))
+            self.PUBKEY_FILE = os.path.expanduser(config.get('auth',
+                                                             'pubkey_file'))
+            self.SERVER = config.get('general', 'server')
+            self.PORT = config.getint('general', 'port')
+        except Exception, msg:
+            raise
+            
     def _getpassphrase(self):
         import getpass
@@ -136,14 +146,13 @@
         return passphrase
         
-    def _catch_failure(self, failure):
-        from twisted.internet import error
+    def _catchFailure(self, failure):
         if failure.check(error.ConnectionRefusedError):
-            print 'Remote server %s refused the connection.'  % (self.server)
-        else:
-            print "Error: ", failure.getErrorMessage()
-            print "Traceback: ", failure.printTraceback()
+            print 'Remote server refused the connection.'
+            return
+        print "Error: ", failure.getErrorMessage()
+        print "Traceback: ", failure.printTraceback()
 
     def _connected(self, remoteobj):
-        if self.log_level > 0:
+        if self.LOG_LEVEL > 0:
             print 'Connected to remote server.\r'
         self.remoteobj = remoteobj
@@ -151,9 +160,8 @@
     
     def _disconnected(self, remoteobj):
-        print '[DSage] Lost connection to %s' % (self.server)
+        print 'Lost connection to the server.'
         self.info_str = 'Not connected.'
 
-    def _got_my_jobs(self, jobs, job_name):
-        from sage.dsage.errors.exceptions import NoJobException
+    def _gotMyJobs(self, jobs, job_name):
         if jobs == None:
             raise NoJobException
@@ -162,24 +170,24 @@
                     for job in jobs if job.name == job_name]
 
-    def _killed_job(self, job_id):
-        pass
+    def _killedJob(self, jobID):
+        if jobID:
+            if self.LOG_LEVEL > 2:
+                print str(jobID) + ' was successfully killed.'
     
     def restore(self, remoteobj):
-        """
+        r"""
         This method restores a connection to the server.
-        
-        """
-        
+        """
         self.remoteobj = remoteobj
 
     def connect(self):
-        """
+        r"""
         This methods establishes the conection to the remote server. 
         
         """
-        
-        from twisted.internet import reactor
-        from sage.dsage.twisted.pb import PBClientFactory
-        factory = PBClientFactory()
+
+        # TODO: Send a useful 'mind' object with the login request!
+        # factory = pb.PBClientFactory()
+        factory = ClientPBClientFactory()
 
         if self.SSL == 1:
@@ -195,5 +203,5 @@
         return factory.login(self.creds, None).addCallback(
                             self._connected).addErrback(
-                            self._catch_failure)
+                            self._catchFailure)
 
     def disconnect(self):
@@ -202,5 +210,5 @@
 
     def eval(self, cmd, globals_=None, job_name=None):
-        """
+        r"""
         eval evaluates a command
 
@@ -214,10 +222,10 @@
         self.check_connected()
         if not job_name or not isinstance(job_name, str):
-            job_name = 'default job'
-        
-        type_ = 'sage'
-
-        job = Job(id_=None, code=cmd, name=job_name,
-                  username=self.username, type_=type_)
+            job_name = 'default_job'
+        
+        type = 'sage'
+
+        job = Job(id=None, file=cmd, name=job_name,
+                  author=self.username, type=type)
 
         wrapped_job = JobWrapper(self.remoteobj, job)
@@ -229,5 +237,5 @@
 
     def eval_file(self, fname, job_name):
-        """
+        r"""
         eval_file allows you to evaluate the contents of an entire file.
 
@@ -239,8 +247,8 @@
         self.check_connected()
 
-        type_ = 'file'
+        type = 'file'
         cmd = open(fname).read()
-        job = Job(id_=None, code=cmd, name=job_name,
-                  username=self.username, type_=type_)
+        job = Job(id=None, file=cmd, name=job_name,
+                  author=self.username, type=type)
         
         wrapped_job = JobWrapper(self.remoteobj, job)
@@ -249,5 +257,5 @@
 
     def send_job(self, job):
-        """
+        r"""
         Sends a Job object to the server.
         
@@ -259,13 +267,13 @@
         return wrapped_job
 
-    def _got_job_id(self, id_, job):
-        job.job_id = id_
-        job.username = self.username
+    def _gotJobID(self, id, job):
+        job.id = id
+        job.author = self.username
 
         self.jobs.append(job)
         
         pickled_job = job.pickle()
-        d = self.remoteobj.callRemote('submit_job', pickled_job)
-        d.addErrback(self._catch_failure)
+        d = self.remoteobj.callRemote('submitJob', pickled_job)
+        d.addErrback(self._catchFailure)
         # d.addCallback(self._submitted, job)
 
@@ -273,5 +281,4 @@
 
     def eval_dir(self, dir, job_name):
-        from twisted.internet import defer
         self.check_connected()
         os.chdir(dir)
@@ -280,27 +287,27 @@
         for file in files:
             sage_cmd = open(file).readlines()
-            d = self.remoteobj.callRemote('get_next_job_id')
-            d.addCallback(self._got_id, sage_cmd, job_name, file=True,
-                          type_='spyx') 
-            d.addErrback(self._catch_failure)
+            d = self.remoteobj.callRemote('getNextJobID')
+            d.addCallback(self._gotID, sage_cmd, job_name, file=True,
+                          type='spyx') 
+            d.addErrback(self._catchFailure)
             deferreds.append(d)
         d_list = defer.DeferredList(deferreds)
         return d_list
 
-    def kill(self, job_id):
-        """
+    def kill(self, jobID):
+        r"""
         Kills a job given the job id. 
 
         Parameters:
-        job_id -- job id
-
-        """
-        
-        d = self.remoteobj.callRemote('kill_job', job_id)
-        d.addCallback(self._killed_job)
-        d.addErrback(self._catch_failure)
+        jobID -- job id
+
+        """
+        
+        d = self.remoteobj.callRemote('killJob', jobID)
+        d.addCallback(self._killedJob)
+        d.addErrback(self._catchFailure)
     
     def get_my_jobs(self, is_active=False, job_name=None):
-        """
+        r"""
         This method returns a list of jobs that belong to you.
 
@@ -315,15 +322,15 @@
         self.check_connected()
 
-        d = self.remoteobj.callRemote('get_jobs_by_username', 
+        d = self.remoteobj.callRemote('getJobsByAuthor', 
                                       self.username,
                                       is_active,
                                       job_name)
-        d.addCallback(self._got_my_jobs, job_name)
-        d.addErrback(self._catch_failure)
+        d.addCallback(self._gotMyJobs, job_name)
+        d.addErrback(self._catchFailure)
         
         return d
 
     def cluster_speed(self):
-        """
+        r"""
         Returns the speed of the cluster. 
         
@@ -332,9 +339,7 @@
         self.check_connected()
 
-        return self.remoteobj.callRemote('get_cluster_speed')
+        return self.remoteobj.callRemote('getClusterSpeed')
 
     def check_connected(self):
-        from sage.dsage.errors.exceptions import NotConnectedException
-        
         if self.remoteobj == None:
             raise NotConnectedException
@@ -343,46 +348,24 @@
 
 class BlockingDSage(DSage):
+    r"""This is the blocking version of DSage
     """
-    This is the blocking version of the DSage interface.
-    
-    """
-
-    def __init__(self, server=None, port=None, username=None, pubkey_file=None, privkey_file=None):
-        from twisted.cred import credentials
-        from twisted.conch.ssh import keys
-        from twisted.spread import banana
-        banana.SIZE_LIMIT = 100*1024*1024 # 100 MegaBytes
-        
-        self.conf = get_conf(type='client')
+
+    def __init__(self, server=None, port=8081, username=None, 
+                 pubkey_file=None, privkey_file=None):
+        self._getconf()
         if server is None:
-            self.server = self.conf['server']
+            self.server = self.SERVER
         else:
             self.server = server
-        if port is None:
-            if self.server == 'localhost':
-                conf = get_conf(type='server')
-                self.port = int(conf['client_port'])
-            else:
-                self.port = int(self.conf['port'])
-        else:
-            self.port = port
-        if username is None:
-            self.username = self.conf['username']
-        else:
-            self.username = username
-        if pubkey_file is None:
-            self.pubkey_file = self.conf['pubkey_file']
-        else:
-            self.pubkey_file = pubkey_file
-        if privkey_file is None:
-            self.privkey_file = self.conf['privkey_file']
-        else:
-            self.privkey_file = privkey_file
-        
-        self.data = self.conf['data']
-        self.ssl = int(self.conf['ssl'])
-        self.log_level = int(self.conf['log_level'])
+
+        self.port = self.PORT
+        self.username = self.USERNAME
+        self.pubkey_file = self.PUBKEY_FILE
+        self.privkey_file = self.PRIVKEY_FILE
+
         self.remoteobj = None
-        self.result = None 
+        self.result = None
+
+        # passphrase = self._getpassphrase()
 
         # public key authentication information
@@ -402,11 +385,13 @@
         self.alg_name = 'rsa'
         self.blob = keys.makePublicKeyBlob(self.pub_key)
+        self.data = self.DATA
         self.signature = keys.signData(self.priv_key, self.data)
         self.creds = credentials.SSHPrivateKey(self.username,
-                                               self.alg_name, 
-                                               self.blob, 
-                                               self.data,
-                                               self.signature)
-
+                                                self.alg_name,
+                                                self.blob, 
+                                                self.data,
+                                                self.signature)
+
+        self.jobs = []
         self.dsage_thread = DSageThread()
         self.dsage_thread.start()
@@ -414,33 +399,30 @@
         
     def connect(self):
-        """
+        r"""
         This methods establishes the conection to the remote server. 
 
         """
-        
-        from twisted.internet import reactor
-        from sage.dsage.twisted.pb import PBClientFactory
-
-        self.factory = PBClientFactory()
-
-        if self.ssl:
+
+        # TODO: Send a useful 'mind' object with the login request!
+        # factory = pb.PBClientFactory()
+        factory = ClientPBClientFactory()
+
+        if self.SSL == 1:
             from twisted.internet import ssl
             contextFactory = ssl.ClientContextFactory()
-            blocking_call_from_thread(reactor.connectSSL,
+            blockingCallFromThread(reactor.connectSSL,
                                    self.server, self.port,
-                                   self.factory, contextFactory) 
+                                   factory, contextFactory) 
         else:
-            blocking_call_from_thread(reactor.connectTCP,
+            blockingCallFromThread(reactor.connectTCP,
                                    self.server, self.port, 
-                                   self.factory)
-
-        d = self.factory.login(self.creds, None)
-        d.addCallback(self._connected)
-        d.addErrback(self._catch_failure)
-        
-        return d
+                                   factory)
+
+        return factory.login(self.creds, None).addCallback(
+                            self._connected).addErrback(
+                            self._catchFailure)
                             
     def eval(self, cmd, globals_=None, job_name=None, async=False):
-        """
+        r"""
         eval evaluates a command
 
@@ -457,8 +439,8 @@
             job_name = 'default_job'
 
-        type_ = 'sage'
-
-        job = Job(id_=None, code=cmd, name=job_name,
-                  username=self.username, type_=type_)
+        type = 'sage'
+
+        job = Job(id=None, file=cmd, name=job_name,
+                  author=self.username, type=type)
 
         if globals_ is not None:
@@ -469,10 +451,10 @@
             wrapped_job = JobWrapper(self.remoteobj, job)
         else:
-            wrapped_job = BlockingJobWrapper(self.remoteobj, job)
+            wrapped_job = blockingJobWrapper(self.remoteobj, job)
         
         return wrapped_job
         
     def send_job(self, job, async=False):
-        """
+        r"""
         Sends a Job object to the server.
 
@@ -488,38 +470,10 @@
             wrapped_job = JobWrapper(self.remoteobj, job)
         else:
-            wrapped_job = BlockingJobWrapper(self.remoteobj, job)
+            wrapped_job = blockingJobWrapper(self.remoteobj, job)
 
         return wrapped_job
         
-    def get_my_jobs(self, active=True):
-        """
-        This method returns a list of jobs that belong to you.
-
-        Parameters:
-        active -- set to true to get only active jobs (bool)
-
-        Use this method if you get disconnected from the server and wish to
-        retrieve your old jobs back.
-
-        """
-
-        self.check_connected()
-        
-        if active:
-            jdicts = blocking_call_from_thread(self.remoteobj.callRemote,
-                                               'get_jobs_by_username',
-                                               self.username,
-                                               active)
-        else:
-            jdicts = blocking_call_from_thread(self.remoteobj.callRemote,
-                                               'get_jobs_by_username',
-                                               self.username,
-                                               False)
-                                           
-        return [expand_job(jdict) for jdict in jdicts]
-        
-        
     def cluster_speed(self):
-        """
+        r"""
         Returns the speed of the cluster. 
 
@@ -528,8 +482,9 @@
         self.check_connected()
 
-        return blocking_call_from_thread(self.remoteobj.callRemote, 'get_cluster_speed')
-    
-    def get_monitors_list(self):
-        """Returns a list of monitors connected to the server.
+        return blockingCallFromThread(self.remoteobj.callRemote,
+                                      'getClusterSpeed')
+    
+    def list_workers(self):
+        r"""Returns a list of workers connected to the server.
         
         """                   
@@ -537,8 +492,9 @@
         self.check_connected()
         
-        return blocking_call_from_thread(self.remoteobj.callRemote, 'get_monitor_list')
-    
-    def get_clients_list(self):
-        """
+        return blockingCallFromThread(self.remoteobj.callRemote,
+                                      'getWorkerList')
+    
+    def list_clients(self):
+        r"""
         Returns a list of clients connected to the server.
         """
@@ -546,18 +502,9 @@
         self.check_connected()
         
-        return blocking_call_from_thread(self.remoteobj.callRemote, 'get_client_list')
-    
-    def get_worker_count(self):
-        """
-        Returns the number of busy and free workers.
-        
-        """
-        
-        self.check_connected()
-        
-        return blocking_call_from_thread(self.remoteobj.callRemote, 'get_worker_count')
-        
+        return blockingCallFromThread(self.remoteobj.callRemote,
+                                      'getClientList')
+                                      
 class JobWrapper(object):
-    """
+    r"""
     Represents a remote job. 
     
@@ -574,10 +521,14 @@
         # TODO Make this more complete
         self._update_job(job)
-
-        # d = self.remoteobj.callRemote('get_next_job_id')
-        d = self.remoteobj.callRemote('submit_job', job.reduce())
-        d.addCallback(self._got_jdict)
-        d.addErrback(self._catch_failure)
-
+        self.worker_info = self._job.worker_info
+
+        d = self.remoteobj.callRemote('getNextJobID')
+        d.addCallback(self._gotID)
+        d.addErrback(self._catchFailure)
+        
+        # hack to try and fetch a result after submitting the job
+        # self.syncJob_task = task.LoopingCall(self.syncJob)
+        # self.syncJob_task.start(2.0, now=True)
+        
     def __repr__(self):
         if self._job.status == 'completed' and not self._job.output:
@@ -591,6 +542,5 @@
         d = copy.copy(self.__dict__)
         d['remoteobj'] = None
-        d['sync_job_task'] = None
-        
+        d['syncJob_task'] = None
         return d
     
@@ -609,5 +559,4 @@
     
     def wait(self):
-        from twisted.internet import reactor
         timeout = 0.1
         while self._job.result is None:
@@ -620,13 +569,7 @@
         f = open(filename, 'w')
         cPickle.dump(self, f, 2)
-        
         return filename
-    
-    def restore(self, dsage):
-        self.remoteobj = dsage.remoteobj
-
-    def _catch_failure(self, failure):
-        from twisted.internet import error
-        from twisted.spread import pb
+
+    def _catchFailure(self, failure):
         if failure.check(pb.DeadReferenceError, error.ConnectionLost):
             print 'Disconnected from server.'
@@ -635,56 +578,52 @@
             print "Traceback: ", failure.printTraceback()
     
-    def _got_job(self, job):
+    def _gotJob(self, job):
         if job == None:
             return
-        self._job = expand_job(job)
+        self._job = self.unpickle(job)
         self._update_job(self._job)
 
-    def _got_jdict(self, jdict):
-        self._job = expand_job(jdict)
-        self.job_id = jdict['job_id']
-        self._update_job(self._job)
-        
-    def get_job(self):
-        from sage.dsage.errors.exceptions import NotConnectedException
-        
+    def _gotID(self, id_):
+        self._job.id = id_
+        self.id = id_
+        pickled_job = self._job.pickle()
+        d = self.remoteobj.callRemote('submitJob', pickled_job)
+        d.addErrback(self._catchFailure)
+
+    def getJob(self):
         if self.remoteobj is None:
             raise NotConnectedException
-        if self.job_id is None:
-            return
-        d = self.remoteobj.callRemote('get_job_by_id', self.job_id)
-        d.addCallback(self._got_job)
-        d.addErrback(self._catch_failure)
-        
+        if self.id is None:
+            return
+        d = self.remoteobj.callRemote('getJobByID', self.id)
+        d.addCallback(self._gotJob)
+        d.addErrback(self._catchFailure)
         return d
 
-    def get_job_output(self):
+    def getJobOutput(self):
         if self.remoteobj == None:
             return
-        d = self.remoteobj.callRemote('get_job_output_by_id', self._job.job_id)
-        d.addCallback(self._got_job_output)
-        d.addErrback(self._catch_failure)
-        
+        d = self.remoteobj.callRemote('getJobOutputByID', self._job.id)
+        d.addCallback(self._gotJobOutput)
+        d.addErrback(self._catchFailure)
         return d
 
-    def _got_job_output(self, output):
+    def _gotJobOutput(self, output):
         self.output = output
         self._job.output = output
 
-    def get_job_result(self):
+    def getJobResult(self):
         if self.remoteobj == None:
             return
-        d = self.remoteobj.callRemote('get_job_result_by_id', self._job.job_id)
-        d.addCallback(self._got_job_result)
-        d.addErrback(self._catch_failure)
-        
+        d = self.remoteobj.callRemote('getJobResultByID', self._job.id)
+        d.addCallback(self._gotJobResult)
+        d.addErrback(self._catchFailure)
         return d
 
-    def _got_job_result(self, result):
+    def _gotJobResult(self, result):
         self.result = result
         self._job.result = result
 
-    def sync_job(self):
-        from twisted.spread import pb
+    def syncJob(self):
         if self.remoteobj == None:
             if self.LOG_LEVEL > 2:
@@ -693,20 +632,20 @@
         if self.status == 'completed':
             if self.LOG_LEVEL > 2:
-                print 'Stopping sync_job'
-            if self.sync_job_task:
-                if self.sync_job_task.running:
-                    self.sync_job_task.stop()
+                print 'Stopping syncJob'
+            if self.syncJob_task:
+                if self.syncJob_task.running:
+                    self.syncJob_task.stop()
             return
             
         try:
-            d = self.remoteobj.callRemote('sync_job', self._job.job_id)
+            d = self.remoteobj.callRemote('syncJob', self._job.id)
         except pb.DeadReferenceError:
-            if self.sync_job_task:
-                if self.sync_job_task.running:
-                    self.sync_job_task.stop()
+            if self.syncJob_task:
+                if self.syncJob_task.running:
+                    self.syncJob_task.stop()
             return
             
-        d.addCallback(self._got_job)
-        d.addErrback(self._catch_failure)
+        d.addCallback(self._gotJob)
+        d.addErrback(self._catchFailure)
 
     def write_result(self, filename):
@@ -720,112 +659,94 @@
 
     def kill(self):
-        """
+        r"""
         Kills the current job.
         
         """
         
-        if self.job_id is not None:
-            d = self.remoteobj.callRemote('kill_job', self.job_id)
-            d.addCallback(self._killed_job)
-            d.addErrback(self._catch_failure)
-            return d
-        else:
-            return
-            
-    def _killed_job(self, job_id):
-        return
-
-class BlockingJobWrapper(JobWrapper):
-    """
-    Blocking version of the JobWrapper object.  This is to be used 
-    interactively.
-    
-    """
-    
+        d = self.remoteobj.callRemote('killJob', self.id)
+        d.addCallback(self._killedJob)
+        d.addErrback(self._catchFailure)
+        return d
+        
+    def _killedJob(self, jobID):
+        if jobID:
+            if self.LOG_LEVEL > 2:
+                print str(jobID) + ' was successfully killed.\r'
+
+class blockingJobWrapper(JobWrapper):
     def __init__(self, remoteobj, job):
         self.remoteobj = remoteobj
         self._job = job
         
+        # TODO Make this more complete
         self._update_job(job)
-
-        jdict = blocking_call_from_thread(self.remoteobj.callRemote, 'submit_job', job.reduce())
-        self._job = expand_job(jdict)
+        self.worker_info = self._job.worker_info
+
+
+        # This is kind of stupid, why not just set the job ID when 
+        # submitting the job?
+        
+        jobID = blockingCallFromThread(self.remoteobj.callRemote,
+                                   'getNextJobID')
+                                           
+        self._job.id = jobID
+        pickled_job = self._job.pickle()
+        d = blockingCallFromThread(self.remoteobj.callRemote,
+                                   'submitJob', pickled_job)
 
     def __repr__(self):
-        if self.killed:
-            return 'Job %s was killed' % (self.job_id)
-        if self.status != 'completed':
-            self.get_job()   
+        self.getJob()
         if self.status == 'completed' and not self.output:
-            return 'No output.'      
-        if not self.output:
+            return 'No output.'
+        elif not self.output:
             return 'No output yet.'
-        else:
-            return self.output
-                    
-    def get_job(self):
-        from sage.dsage.errors.exceptions import NotConnectedException
-        
+
+        return self.output
+        
+    def getJob(self):
         if self.remoteobj == None:
            raise NotConnectedException
         if self.status == 'completed':
             return
-        
-        job = blocking_call_from_thread(
-                        self.remoteobj.callRemote, 'get_job_by_id', self._job.job_id)
-        
-        self._update_job(expand_job(job))
-    
-    def async_get_job(self):
-        return JobWrapper.get_job(self)
+            
+        job = blockingCallFromThread(self.remoteobj.callRemote,
+                                     'getJobByID', self._job.id)
+        
+        self._update_job(self.unpickle(job))
+    
+    def async_getJob(self):
+        # if self.remoteobj == None:
+        #     raise NotConnectedException
+        # d = self.remoteobj.callRemote('getJobByID', self._job.id)
+        # d.addCallback(self._gotJob)
+        # d.addErrback(self._catchFailure)
+        return JobWrapper.getJob(self)
+        # return d
         
     def kill(self):
-        """
+        r"""
         Kills the current job.
 
         """
-        
-        job_id = blocking_call_from_thread(self.remoteobj.callRemote, 'kill_job', self._job.job_id)
-        self.job_id = job_id
-        self.killed = True
-        
-        return job_id
+
+        jobID = blockingCallFromThread(self.remoteobj.callRemote,
+                                   'killJob', self._job.id)
+        return jobID
     
     def async_kill(self):
-        """
+        r"""
         async version of kill
         
         """
         
-        d = self.remoteobj.callRemote('kill_job', self.job_id)
-        d.addCallback(self._killed_job)
-        d.addErrback(self._catch_failure)
-        
+        print 'Killing ', self.id
+        d = self.remoteobj.callRemote('killJob', self.id)
+        d.addCallback(self._killedJob)
+        d.addErrback(self._catchFailure)
         return d
         
-    def wait(self, timeout=None):
-        """
-        Waits on a job until it is completed. 
-        
-        Parameters:
-        timeout -- number of seconds to wait, if it has not completed by then
-                   it will raise RunTimeError if it is set to None, 
-                   it will wait indefinitely until the job is completed
-                   
-        """
-        
-        import signal
-        
-        if timeout is None:
-            while self.status != 'completed':
-                time.sleep(1.0)
-                self.get_job()
-        else:
-            def handler(signum, frame):
-                raise RuntimeError, 'Maximum wait time exceeded.'
-            signal.signal(signal.SIGALRM, handler)
-            signal.alarm(timeout)
-            while self.status != 'completed':
-                time.sleep(1.0)
-                self.get_job()
-            signal.alarm(0)    
+    def wait(self):
+        timeout = 0.1
+        while self.result is None:
+            time.sleep(timeout)
+            self.getJob()            
Index: age/dsage/misc/config.py
===================================================================
--- sage/dsage/misc/config.py	(revision 3902)
+++ 	(revision )
@@ -1,89 +1,0 @@
-##############################################################################
-#                                                                     
-#  DSAGE: Distributed SAGE                     
-#                                                                             
-#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
-#                                                                            
-#  Distributed under the terms of the GNU General Public License (GPL)        
-#
-#    This code 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
-#    General Public License for more details.
-#
-#  The full text of the GPL is available at:
-#
-#                  http://www.gnu.org/licenses/
-#
-##############################################################################
-
-"""
-Gets the different configuration options for the various components of DSAGE.
-"""
-
-import os
-import random
-import ConfigParser
-import uuid
-
-def check_version(old_version):
-    from sage.dsage.__version__ import version
-    if version != old_version:
-        raise ValueError, "Incompatible version. You have %s, need %s." % (old_version, version)
-
-def read_conf(config):
-    conf = {}
-    for sec in config.sections():
-        conf.update(dict(config.items(sec)))
-    check_version(conf['version'])
-
-    return conf
-    
-def get_conf(type):
-    DSAGE_DIR = os.path.join(os.getenv('DOT_SAGE'), 'dsage')
-    config = ConfigParser.ConfigParser()
-    try:
-        if type == 'client':   
-            conf_file = os.path.join(DSAGE_DIR, 'client.conf')
-            DATA =  ''.join([chr(i) for i in [random.randint(65, 123) for n in range(500)]])
-            config.read(conf_file)
-            conf = read_conf(config)
-            conf['data'] = DATA
-        elif type == 'server':
-            conf_file = os.path.join(DSAGE_DIR, 'server.conf')
-            config.read(conf_file)
-            conf = read_conf(config)
-        elif type == 'monitor':
-            conf_file = os.path.join(DSAGE_DIR, 'worker.conf')
-            config.read(conf_file)
-            if len(config.get('uuid', 'id')) != 36:
-                config.set('uuid', 'id', str(uuid.uuid1()))
-                f = open(conf_file, 'w')
-                config.write(f)
-                config.read(conf_file)
-            conf = read_conf(config)
-        elif type == 'jobdb' or type == 'clientdb' or type == 'monitordb':
-            conf_file = os.path.join(DSAGE_DIR, 'server.conf')
-            config.read(conf_file)
-            conf = read_conf(config)
-            conf['log_level'] = config.get('db_log', 'log_level')
-            conf['log_file'] = config.get('db_log', 'log_file')
-
-        return conf 
-    except Exception, msg:
-        print msg
-        print "Error reading '%s', run dsage.setup()" % conf_file     
-
-def get_bool(value):
-    boolean_states = {'0': False,
-    '1': True,
-    'false': False,
-    'no': False,
-    'off': False,
-    'on': True,
-    'true': True,
-    'yes': True}
-    if value.lower() not in boolean_states:
-        raise ValueError, 'Not a boolean: %s' % value
-    
-    return boolean_states[value.lower()]
Index: age/dsage/misc/constants.py
===================================================================
--- sage/dsage/misc/constants.py	(revision 3769)
+++ 	(revision )
@@ -1,1 +1,0 @@
-delimiter = '-' * 50
Index: sage/dsage/misc/hostinfo.py
===================================================================
--- sage/dsage/misc/hostinfo.py	(revision 3866)
+++ sage/dsage/misc/hostinfo.py	(revision 2885)
@@ -31,9 +31,9 @@
         return str(self.host_info)
 
-    def _catch_failure(self, failure):
+    def _catchFailure(self, failure):
         log.msg("Error: ", failure.getErrorMessage())
         log.msg("Traceback: ", failure.printTraceback())
 
-    def _gotsysctl(self, output, host_info):
+    def _gotsysctl(self, output, host_info_mac):
         d = defer.Deferred()
         output = output.split('\n')
@@ -49,16 +49,13 @@
             l = [li.strip() for li in l]
             if l[0] == 'hw.cpufrequency':
-                host_info['cpu Mhz'] = str(int(l[1]) / 1000000.0)
+                host_info_mac['cpu Mhz'] = str(int(l[1]) / 1000000.0)
             elif l[0] == 'hw.availcpu':
-                host_info['cpus'] = int(l[1])
+                host_info_mac['cpus'] = int(l[1])
             elif l[0] == 'hw.physmem':
-                host_info['MemTotal'] = int(l[1])
+                host_info_mac['MemTotal'] = int(l[1])
             elif l[0] == 'hw.usermem':
-                host_info['MemFree'] = (host_info['MemTotal'] - 
+                host_info_mac['MemFree'] = (host_info_mac['MemTotal'] - 
                                            int(l[1])) / 1024 / 1024
-            elif l[0] == 'machdep.cpu.brand_string':
-                host_info['cpu model'] = l[1]
-                
-        self.canonical_info(host_info)
+        self.canonical_info(host_info_mac)
         d.callback(self.host_info)
         return d
@@ -66,8 +63,8 @@
     def get_host_info(self):
         platform = sys.platform
-        host_info = {}
         if platform == 'linux2' or platform == 'linux':
             d = defer.Deferred()
-            host_info['os'] = platform
+            host_info_linux = {}
+            host_info_linux['os'] = platform
             cpuinfo = open('/proc/cpuinfo','r').readlines()
 
@@ -82,11 +79,11 @@
                 s = line.split(':')
                 if s != ['\n']:
-                    host_info[s[0].strip()] = s[1].strip()
+                    host_info_linux[s[0].strip()] = s[1].strip()
 
-            host_info['cpus'] = cpus
+            host_info_linux['cpus'] = cpus
             
             # uptime
             uptime = open('/proc/uptime', 'r').readline().split(' ')
-            host_info['uptime'] = uptime[0]
+            host_info_linux['uptime'] = uptime[0]
 
             # memory info
@@ -95,37 +92,37 @@
                 s = line.split(':')
                 if s != ['\n']:
-                    host_info[s[0].strip()] = s[1].strip()
+                    host_info_linux[s[0].strip()] = s[1].strip()
 
             # hostname
             hostname = os.popen('hostname').readline().strip()
-            host_info['hostname'] = hostname
+            host_info_linux['hostname'] = hostname
 
             # kernel version
             kernel_version = os.popen('uname -r').readline().strip()
-            host_info['kernel_version'] = kernel_version
+            host_info_linux['kernel_version'] = kernel_version
 
-            host_info['os'] = platform
-            d.callback(self.canonical_info(host_info))
+            host_info_linux['os'] = platform
+            d.callback(self.canonical_info(host_info_linux))
             return d
 
         if platform == 'darwin':
             """OS X Worker. """
+            host_info_mac = {}
             cmd = '/usr/sbin/sysctl'
             args = ('-a', 'hw')
             d = utils.getProcessOutput(cmd, args, errortoo=1)
-            d.addCallback(self._gotsysctl, host_info)
-            d.addErrback(self._catch_failure)
+            d.addCallback(self._gotsysctl, host_info_mac)
+            d.addErrback(self._catchFailure)
             return d
-                
+
     def canonical_info(self, platform_host_info):
         """Standarize host info so we can parse it easily"""
 
-        unify_info = {'model name': 'cpu_model', 
+        unify_info = {'model name': 'cpu_name', 
                           'cpu Mhz': 'cpu_speed',
-                          'MemTotal': 'mem_total',
-                          'MemFree': 'mem_free',
+                          'MemTotal': 'total_mem',
+                          'MemFree': 'free_mem',
                           'kernel_version': 'os',
-                          'cpu family': 'cpu_model',
-                          'cpu model': 'cpu_model',
+                          'cpu family': 'cpu_family',
                           'cache size': 'cpu_cache_size',
                           'fpu': 'fpu',
@@ -142,139 +139,9 @@
             except KeyError:
                 pass
-        
-        import sage.version
-        canonical_info['sage_version'] = sage.version.version
-        
+
         self.host_info = canonical_info
         return self.host_info
 
-class ClassicHostInfo(object):
-    """
-    Class to gather computer specifications on the running host.
-    
-    """
-    
-    def __init__(self):
-        self.host_info = self.get_host_info(sys.platform)
-
-    def __str__(self):
-        return str(self.host_info)
-
-    def __repr__(self):
-        return str(self.host_info)
-
-    def get_host_info(self, platform):
-        host_info = {}
-        if platform == 'linux2' or platform == 'linux':
-            try:
-                # os
-                host_info['os'] = platform
-                # cpu info
-                cpuinfo = open('/proc/cpuinfo','r').readlines()
-
-                cpus = 0
-                for line in cpuinfo:
-                    if 'processor' in line:
-                        cpus += 1
-                    s = line.split(':')
-                    if s != ['\n']:
-                        host_info[s[0].strip()] = s[1].strip()
-
-                host_info['cpus'] = cpus
-                
-                # uptime
-                uptime = open('/proc/uptime', 'r').readline().split(' ')
-                host_info['uptime'] = uptime[0]
-
-                # memory info
-                meminfo = open('/proc/meminfo', 'r').readlines()
-                for line in meminfo:
-                    s = line.split(':')
-                    if s != ['\n']:
-                        host_info[s[0].strip()] = s[1].strip()
-
-                # hostname
-                hostname = os.popen('hostname').readline().strip()
-                host_info['hostname'] = hostname
-
-                # kernel version
-                kernel_version = os.popen('uname -r').readline().strip()
-                host_info['kernel_version'] = kernel_version
-
-            except IOError:
-                raise
-
-            host_info['os'] = platform
-            return self.canonical_info(host_info)
-			
-        if platform == 'darwin':
-            try:
-                # os
-                for line in os.popen('sysctl -a hw machdep').readlines():
-                    l = line.strip()
-                    if '=' in l:
-                        l = l.split('=')
-                    if ':' in line:
-                        l = l.split(':')
-                    
-                    l = [li.strip() for li in l]
-                    if l[0] == 'hw.cpufrequency':
-                        host_info['cpu MHz'] = str(int(l[1]) / 1000000)
-                    elif l[0] == 'hw.availcpu':
-                        host_info['cpus'] = int(l[1])
-                    elif l[0] == 'hw.physmem':
-                        host_info['MemTotal'] = l[1]
-                    elif l[0] == 'hw.usermem':
-                        host_info['MemFree'] = int(int(host_info['MemTotal']) -
-                                               int(l[1]) / int(1024*2))
-                    elif l[0] == 'machdep.cpu.brand_string':
-                        host_info['model name'] = l[1]
-                                    
-                # hostname
-                hostname = os.popen('hostname').readline().strip()
-                host_info['hostname'] = hostname
-
-                # kernel version
-                kernel_version = os.popen('uname -r').readline().strip()
-                host_info['kernel_version'] = kernel_version
-            except IOError, msg:
-                log.msg(msg)
-                raise
-
-   
-            host_info['os'] = platform
-
-            return self.canonical_info(host_info)
-            
-    def canonical_info(self, platform_host_info):
-        """Standarize host info so we can parse it easily"""
-
-        unify_info = {'model name': 'cpu_model', 
-                          'cpu MHz': 'cpu_speed',
-                          'MemTotal': 'mem_total',
-                          'MemFree': 'mem_free',
-                          'kernel_version': 'kernel_version',
-                          'processor': 'processors',
-                          'cache size': 'cpu_cache_size',
-                          'fpu': 'fpu',
-                          'hostname': 'hostname',
-                          'cpus': 'cpus',
-                          'ip': 'ip',
-                          'os': 'os'
-                     }
-       
-        canonical_info = {}
-        for k,v in platform_host_info.iteritems():
-            try:
-                canonical_info[unify_info[k]] = v
-            except KeyError:
-                pass
-        
-        import sage.version
-        canonical_info['sage_version'] = sage.version.version
-
-        return canonical_info
-
-if __name__ == 'main':
-    h = HostInfo().get_host_info()
-    reactor.run()
+    if __name__ == 'main':
+        h = HostInfo().get_host_info()
+        reactor.run()
Index: age/dsage/scripts/dsage_get_stats.py
===================================================================
--- sage/dsage/scripts/dsage_get_stats.py	(revision 3798)
+++ 	(revision )
@@ -1,37 +1,0 @@
-#!/usr/bin/env python
-##############################################################################
-#                                                                     
-#  DSAGE: Distributed SAGE                     
-#                                                                             
-#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
-#                                                                            
-#  Distributed under the terms of the GNU General Public License (GPL)        
-#
-#    This code 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
-#    General Public License for more details.
-#
-#  The full text of the GPL is available at:
-#
-#                  http://www.gnu.org/licenses/
-#
-##############################################################################
-
-from sage.dsage.server.server import DSageServer
-from sage.dsage.database.jobdb import JobDatabaseSQLite
-from sage.dsage.database.monitordb import MonitorDatabase
-from sage.dsage.database.clientdb import ClientDatabase
-
-def main():
-    jobdb = JobDatabaseSQLite()
-    monitordb = MonitorDatabase()
-    clientdb = ClientDatabase()
-    dsage_server = DSageServer(jobdb, monitordb, clientdb)
-    f = open('dsage.xml', 'w')
-    f.write(dsage_server.generate_xml_stats())
-    f.close()
-    print 'Wrote dsage.xml...'
-    
-if __name__ == '__main__':
-    main()
Index: sage/dsage/scripts/dsage_server.py
===================================================================
--- sage/dsage/scripts/dsage_server.py	(revision 3906)
+++ sage/dsage/scripts/dsage_server.py	(revision 2925)
@@ -21,31 +21,40 @@
 import sys
 import os
-import socket
-
-
-
 from optparse import OptionParser
 import ConfigParser
-import socket
 
-from twisted.internet import reactor, error, ssl, task
+from twisted.internet import reactor, task
 from twisted.spread import pb
 from twisted.python import log
 from twisted.cred import portal
 
-from sage.dsage.database.jobdb import JobDatabaseZODB, JobDatabaseSQLite
-from sage.dsage.database.jobdb import DatabasePruner
-from sage.dsage.database.clientdb import ClientDatabase
-from sage.dsage.database.monitordb import MonitorDatabase
+from sage.dsage.database.jobdb import JobDatabaseZODB, DatabasePruner
 from sage.dsage.twisted.pb import Realm
 from sage.dsage.twisted.pb import WorkerPBServerFactory
 from sage.dsage.twisted.pb import _SSHKeyPortalRoot
 from sage.dsage.twisted.pubkeyauth import PublicKeyCredentialsChecker
-from sage.dsage.twisted.pubkeyauth import PublicKeyCredentialsCheckerDB
 from sage.dsage.server.server import DSageServer, DSageWorkerServer
-from sage.dsage.misc.constants import delimiter as DELIMITER
-from sage.dsage.__version__ import version
 
 DSAGE_DIR = os.path.join(os.getenv('DOT_SAGE'), 'dsage')
+# Begin reading configuration
+try:
+    conf_file = os.path.join(DSAGE_DIR, 'server.conf')
+    config = ConfigParser.ConfigParser()
+    config.read(conf_file)
+    
+    LOG_FILE = config.get('server_log', 'log_file')
+    LOG_LEVEL = config.getint('server_log', 'log_level')
+    SSL = config.getint('ssl', 'ssl')
+    SSL_PRIVKEY = config.get('ssl', 'privkey_file')
+    SSL_CERT = config.get('ssl', 'cert_file')
+    WORKER_PORT = config.getint('server', 'worker_port')
+    CLIENT_PORT = config.getint('server', 'client_port')
+    PUBKEY_DATABASE = os.path.expanduser(config.get('auth',
+                                                    'pubkey_database'))
+except:
+    print "Error reading %s, please fix manually run dsage.setup()" % \
+    conf_file
+    sys.exit(-1)
+# End reading configuration
 
 def usage():
@@ -71,15 +80,4 @@
     return options
 
-def write_stats(dsage_server, stats_file):
-    # Put this entire thing in a try block, should not cause the server to die in any way.
-    try:
-        fname = os.path.join(DSAGE_DIR, stats_file)
-        f = open(fname, 'w')
-        f.write(dsage_server.generate_xml_stats())
-        f.close()
-    except Exception, msg:
-        print 'Error writing stats: %s' % (msg)
-        return
-        
 def startLogging(log_file):
     """This method initializes the logging facilities for the server. """
@@ -87,116 +85,60 @@
         log.startLogging(sys.stdout)
     else:
-        print "DSAGE Server logging to file: ", log_file
+        print "Logging to file: ", log_file
         server_log = open(log_file, 'a')
         log.startLogging(server_log)
 
 def main():
-    """
-    Main execution loop of the server.
+    """Main execution loop of the server."""
     
-    """
+    options = usage()
+    jobdb = JobDatabaseZODB()
     
-    try:
-        conf_file = os.path.join(DSAGE_DIR, 'server.conf')
-        config = ConfigParser.ConfigParser()
-        config.read(conf_file)
-
-        LOG_FILE = config.get('server_log', 'log_file')
-        LOG_LEVEL = config.getint('server_log', 'log_level')
-        SSL = config.getint('ssl', 'ssl')
-        SSL_PRIVKEY = config.get('ssl', 'privkey_file')
-        SSL_CERT = config.get('ssl', 'cert_file')
-        CLIENT_PORT = config.getint('server', 'client_port')
-        PUBKEY_DATABASE = os.path.expanduser(config.get('auth', 'pubkey_database'))
-        STATS_FILE = config.get('general', 'stats_file')
-        old_version = config.get('general', 'version')
-        if version != old_version:
-            raise ValueError, "Incompatible version. You have %s, need %s." % (old_version, version)
-    except Exception, msg:
-        print msg
-        print "Error reading %s, run dsage.setup()" % conf_file
-        sys.exit(-1)
+    # Start to prune out old jobs
+    jobdb_pruner = DatabasePruner(jobdb)
+    prune_db = task.LoopingCall(jobdb_pruner.prune)
+    prune_db.start(60*60*24.0, now=True) # start now, interval is one day
+    
+    # Create the main DSage object
+    dsage_server = DSageServer(jobdb, log_level=LOG_LEVEL)
+    p = _SSHKeyPortalRoot(portal.Portal(Realm(dsage_server)))
+    
+    # Get authorized keys
+    p.portal.registerChecker(PublicKeyCredentialsChecker(PUBKEY_DATABASE))
+    
+    # HACK: unsafeTracebacks should eventually be TURNED off
+    client_factory = pb.PBServerFactory(p, unsafeTracebacks=True)
+    
+    # Create the PBServerFactory for workers
+    dsage_worker = DSageWorkerServer(jobdb, log_level=LOG_LEVEL)
+    worker_factory = WorkerPBServerFactory(dsage_worker)
+    
+    # We will listen on 2 ports
+    # One port that is authenticated so clients can submit new jobs
+    # One port for workers to connect to to receive and submit jobs
+    if SSL == 1:
+        from twisted.internet import ssl
+        sslContext = ssl.DefaultOpenSSLContextFactory(
+                    SSL_PRIVKEY,
+                    SSL_CERT)
+        
+        reactor.listenSSL(CLIENT_PORT,
+                          client_factory,
+                          contextFactory = sslContext)
+        reactor.listenSSL(WORKER_PORT,
+                          worker_factory,
+                          contextFactory = sslContext)
+    
+    else:
+        reactor.listenTCP(CLIENT_PORT, client_factory)
+        reactor.listenTCP(WORKER_PORT, worker_factory)
+    
+    dsage_server.client_factory = client_factory
+    dsage_server.worker_factory = worker_factory
     
     # start logging
     startLogging(LOG_FILE)
     
-    # Job database
-    jobdb = JobDatabaseSQLite()
-    
-    # Worker database
-    monitordb = MonitorDatabase()
-    
-    # Client database
-    clientdb = ClientDatabase()
-    
-    # Create the main DSage object
-    dsage_server = DSageServer(jobdb, monitordb, clientdb, log_level=LOG_LEVEL)
-    p = _SSHKeyPortalRoot(portal.Portal(Realm(dsage_server)))
-    
-    # Credentials checker
-    p.portal.registerChecker(PublicKeyCredentialsCheckerDB(clientdb))
-    
-    # HACK: unsafeTracebacks should eventually be TURNED off
-    client_factory = pb.PBServerFactory(p, unsafeTracebacks=True)
-    
-    # Create the looping call that will output the XML file for Dashboard
-    tsk1 = task.LoopingCall(write_stats, dsage_server, STATS_FILE)
-    tsk1.start(5.0, now=False)
-    
-    # Create the PBServerFactory for workers
-    # Use this for unauthorized workers
-    # dsage_worker = DSageWorkerServer(jobdb, log_level=LOG_LEVEL)
-    # worker_factory = WorkerPBServerFactory(dsage_worker)
-    
-    dsage_server.client_factory = client_factory
-    
-    attempts = 0
-    err_msg = "Could not find an open port after 50 attempts."
-    NEW_CLIENT_PORT = CLIENT_PORT
-    while True:
-        if attempts > 50:
-            log.err(err_msg)
-            log.err('Last attempted port: %s' % (NEW_CLIENT_PORT))
-            sys.exit(-1)
-        try:
-            try:
-                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-                s.connect(('', NEW_CLIENT_PORT))
-                port_used = True
-            except socket.error, msg:
-                port_used = False
-            if not port_used:
-                if SSL:
-                    log.msg('Using SSL...')
-                    ssl_context = ssl.DefaultOpenSSLContextFactory(SSL_PRIVKEY, SSL_CERT)
-                    reactor.listenSSL(NEW_CLIENT_PORT,
-                                      client_factory,
-                                      contextFactory = ssl_context)
-                    break
-                else:
-                    reactor.listenTCP(NEW_CLIENT_PORT, client_factory)
-                    break
-            else:
-                raise SystemError, 'Trying to bind to open port: %s.' % (NEW_CLIENT_PORT)
-        except (SystemError, error.CannotListenError):
-            attempts += 1
-            NEW_CLIENT_PORT += 1
-
-    if CLIENT_PORT != NEW_CLIENT_PORT:
-        log.msg(DELIMITER)
-        log.msg("***NOTICE***")
-        log.msg("Changing listening port in server.conf to %s" % (NEW_CLIENT_PORT))
-        log.msg(DELIMITER)
-        config.set('server', 'client_port', NEW_CLIENT_PORT)
-        config.write(open(conf_file, 'w'))
-        
-    log.msg(DELIMITER)
-    log.msg('DSAGE Server')
-    log.msg('PID %s'%os.getpid())
-    log.msg('Listening on %s' % (NEW_CLIENT_PORT))
-    log.msg(DELIMITER)
-
-    # start the reactor.    
-    reactor.run(installSignalHandlers=1)
+    reactor.run()
 
 if __name__ == "__main__":
Index: sage/dsage/scripts/dsage_setup.py
===================================================================
--- sage/dsage/scripts/dsage_setup.py	(revision 3905)
+++ sage/dsage/scripts/dsage_setup.py	(revision 2891)
@@ -24,12 +24,9 @@
 import sys
 
-from sage.dsage.database.clientdb import ClientDatabase
-from sage.dsage.misc.constants import delimiter as DELIMITER
-from sage.dsage.__version__ import version
-
-DSAGE_DIR = os.path.join(os.getenv('DOT_SAGE'), 'dsage')    
+DSAGE_DIR = os.path.join(os.getenv('DOT_SAGE'), 'dsage')
+PUBKEY_DATABASE = os.path.abspath(os.path.join(DSAGE_DIR, 
+                                  'authorized_keys.db'))        
 DB_DIR = os.path.join(DSAGE_DIR, 'db/')
 SAGE_ROOT = os.getenv('SAGE_ROOT')
-DSAGE_VERSION = version
 
 def check_dsage_dir():
@@ -43,5 +40,4 @@
     config = ConfigParser.ConfigParser()
     config.add_section('general')
-    config.set('general', 'version', DSAGE_VERSION)
     config.add_section('ssl')
     if type == 'client':
@@ -71,9 +67,7 @@
     config.set('log', 'log_level', '0')
     # set public key authentication info
-    print DELIMITER
     print "Generating public/private key pair for authentication..."
     print "Your key will be stored in %s/dsage_key"%DSAGE_DIR
     print "Just hit enter when prompted for a passphrase"
-    print DELIMITER
     key_file = os.path.join(DSAGE_DIR, 'dsage_key')
     cmd = ["ssh-keygen", "-q", "-trsa", "-f%s" % key_file]    
@@ -84,5 +78,5 @@
     config.set('auth', 'pubkey_file', key_file + '.pub')
     config.write(open(conf_file, 'w'))
-    print "Client configuration finished.\n"
+    print "Client configuration finished."
 
 def setup_worker():
@@ -92,5 +86,5 @@
 
     config.set('general', 'server', 'localhost')
-    config.set('general', 'port', 8081)
+    config.set('general', 'port', 8082)
     config.set('general', 'nice_level', 20)
     config.set('general', 'workers', 2)
@@ -100,8 +94,7 @@
     config.set('log', 'log_level', '0')
     config.set('general', 'delay', '5')
-    config.set('general', 'anonymous', False)
     conf_file = os.path.join(DSAGE_DIR, 'worker.conf')
     config.write(open(conf_file, 'w'))
-    print "Worker configuration finished.\n"
+    print "Worker configuration finished."
 
 def setup_server():
@@ -110,4 +103,5 @@
     config = get_config('server')
     config.set('server', 'client_port', 8081)
+    config.set('server', 'worker_port', 8082)
     config.set('ssl', 'ssl', 1)
     config.set('server_log', 'log_file', 'stdout')
@@ -115,17 +109,18 @@
     config.set('db_log', 'log_file', 'stdout')
     config.set('db_log', 'log_level', '0')
-    config.set('auth', 'pubkey_database', os.path.join(DB_DIR, 'dsage.db'))
-    config.set('db', 'db_file', os.path.join(DB_DIR, 'dsage.db'))
+    config.set('auth', 'pubkey_database', PUBKEY_DATABASE)
+    config.set('db', 'db_file', os.path.join(DB_DIR, 'jobdb.fs'))
     config.set('db', 'prune_in_days', 7)
     config.set('db', 'stale_in_days', 365)
-    config.set('db', 'job_failure_threshold', 2)
+    config.set('db', 'failure_threshhold', 5)
     config.set('ssl', 'privkey_file', os.path.join(DSAGE_DIR, 'cacert.pem'))
-    config.set('ssl', 'cert_file', os.path.join(DSAGE_DIR, 'pubcert.pem'))
-    config.set('general', 'stats_file', 'gauge.xml')
-    
-    print DELIMITER
+    config.set('ssl', 'cert_file', os.path.join(DSAGE_DIR, 'privkey.pem'))
+
+
     print "Generating SSL certificate for server..."
+    print "Creates a private key:"
     cmd = ['openssl genrsa > %s' % (config.get('ssl', 'privkey_file'))]
     subprocess.call(cmd, shell=True)
+    print "Creates a self signed SSL certificate:"
     cmd = ['openssl req  -config %s -new -x509 -key %s -out %s -days \
            1000' % (os.path.join(SAGE_ROOT,'local/openssl/openssl.cnf'),
@@ -133,12 +128,5 @@
                     config.get('ssl', 'cert_file'))]
     subprocess.call(cmd, shell=True)
-    print DELIMITER
-    os.chmod(os.path.join(DSAGE_DIR, 'cacert.pem'), 0600)
-    
-    conf_file = os.path.join(DSAGE_DIR, 'server.conf')
-    config.write(open(conf_file, 'w'))
-    
-    print "Server configuration finished.\n\n"
-        
+
     # add default user
     c = ConfigParser.ConfigParser()
@@ -146,17 +134,19 @@
     username = c.get('auth', 'username')
     pubkey_file = c.get('auth', 'pubkey_file')
-    clientdb = ClientDatabase()
-    if clientdb.get_user_and_key(username) is None:
-        clientdb.add_user(username, pubkey_file)
-        print 'Added user %s\n' % (username)
-    else:
-        (user, key) = clientdb.get_user_and_key(username)
-        pubkey = open(pubkey_file).read()
-        if pubkey != key:
-            clientdb.del_user(username)
-            clientdb.add_user(username, pubkey_file)            
-            print 'User %s exists, changing public key' % (username)
-        else:
-            print 'User %s already exists.' % (username)
+    add_user(username, pubkey_file)
+
+    conf_file = os.path.join(DSAGE_DIR, 'server.conf')
+    config.write(open(conf_file, 'w'))
+
+    print "Server configuration finished."
+    print "\n"
+
+def add_user(username, pubkey_file):
+    f = open(pubkey_file)
+    type, key = f.readlines()[0].split()[:2]
+    f.close()
+    f1 = open(PUBKEY_DATABASE, 'a')
+    f1.write(':'.join([username, key]) + '\n')
+    f1.close()
 
 def setup():
Index: sage/dsage/scripts/dsage_worker.py
===================================================================
--- sage/dsage/scripts/dsage_worker.py	(revision 3906)
+++ sage/dsage/scripts/dsage_worker.py	(revision 2965)
@@ -16,5 +16,4 @@
 #
 #                  http://www.gnu.org/licenses/
-#
 ############################################################################
 
@@ -22,24 +21,17 @@
 import os
 import ConfigParser
+import uuid
 import cPickle
 import zlib
-import pexpect
-import time
 
 from twisted.spread import pb
 from twisted.internet import reactor, defer, error, task
 from twisted.python import log
-from twisted.spread import banana
-banana.SIZE_LIMIT = 100*1024*1024 # 100 MegaBytes
 
 from sage.interfaces.sage0 import Sage
 from sage.misc.preparser import preparse_file
 
-from sage.dsage.database.job import Job, expand_job
-from sage.dsage.misc.hostinfo import HostInfo, ClassicHostInfo
-from sage.dsage.misc.config import get_conf, get_bool
+from sage.dsage.misc.hostinfo import HostInfo
 from sage.dsage.errors.exceptions import NoJobException
-from sage.dsage.twisted.pb import PBClientFactory
-from sage.dsage.misc.constants import delimiter as DELIMITER
 
 pb.setUnjellyableForClass(HostInfo, HostInfo)
@@ -47,4 +39,24 @@
 DSAGE_DIR = os.path.join(os.getenv('DOT_SAGE'), 'dsage')
 
+# Begin reading configuration
+try:
+    conf_file = os.path.join(DSAGE_DIR, 'worker.conf')
+    config = ConfigParser.ConfigParser()
+    config.read(conf_file)
+    
+    LOG_FILE = config.get('log', 'log_file')
+    LOG_LEVEL = config.getint('log','log_level')
+    SSL = config.getint('ssl', 'ssl')
+    WORKERS = config.getint('general', 'workers')
+    SERVER = config.get('general', 'server')
+    PORT = config.getint('general', 'port')
+    DELAY = config.getint('general', 'delay')
+except:
+    print "Error reading %s, please fix manually or run dsage.setup()" % \
+    conf_file
+    sys.exit(-1)
+# End reading configuration
+
+# OUTPUT MARKERS shared by Worker and Monitor
 START_MARKER = '___BEGIN___'
 END_MARKER = '___END___'
@@ -54,5 +66,5 @@
     
 class Worker(object):
-    """
+    r"""
     This class represents a worker object that does the actual calculation.
     
@@ -67,8 +79,6 @@
         self.free = True
         self.job = None
-        self.conf = get_conf('monitor')
-        self.log_level = self.conf['log_level']
-        self.delay = self.conf['delay']
-        if self.log_level > 3:
+        
+        if LOG_LEVEL > 3:
             self.sage = Sage(logfile=DSAGE_DIR + '/%s-pexpect.log'\
                              % self.id)
@@ -82,20 +92,16 @@
         
         # Initialize getting of jobs
-        self.get_job()
-        
-    def _catch_failure(self, failure):
-        log.msg("Error: ", failure.getErrorMessage())
-        log.msg("Traceback: ", failure.printTraceback())
-        
-    def get_job(self):
+        self.getJob()
+
+    def getJob(self):
+        # print 'Ok so far.'
         try:
-            if self.log_level > 3:
-                log.msg('Worker %s: Getting job...' % (self.id))
-            d = self.remoteobj.callRemote('get_job')
+            d = self.remoteobj.callRemote('getJob')
         except Exception, msg:
-            log.msg(msg)
-            log.msg('[Worker: %s, get_job] Disconnected from remote server.'\
+            print 'Error getting job.'
+            print msg
+            log.msg('[Worker: %s, getJob] Disconnected from remote server.'\
                     % self.id)
-            reactor.callLater(self.delay, self.get_job)
+            reactor.callLater(DELAY, self.getJob)
             return
         d.addCallback(self.gotJob)
@@ -104,33 +110,29 @@
         return d
     
-    def gotJob(self, jdict):
-        """
-        gotJob is a callback for the remoteobj's get_job method.
+    def gotJob(self, job):
+        r"""
+        gotJob is a callback for the remoteobj's getJob method.
         
         Parameters:
-        job -- Job object returned by remote's 'get_job' method
-        
-        """
-        
-        if self.log_level > 3:
-            log.msg('[Worker %s, gotJob] %s' % (self.id, jdict))
-            
-        self.job = expand_job(jdict)
-        
-        if not isinstance(self.job, Job):
+        job -- Job object returned by remote's 'getJob' method
+        
+        """
+        
+        if not isinstance(job, str):
             raise NoJobException
         
-        log.msg('[Worker: %s] Got job (%s, %s)' % (self.id, self.job.name, self.job.job_id))
+        self.job = unpickle(job)
+        log.msg('[Worker: %s] Got job (%s, %s)' % (self.id,
+                                                   self.job.name, 
+                                                   self.job.id))
         try:
             self.doJob(self.job)
-        except Exception, msg:
-            log.msg(msg)
-            d = self.remoteobj.callRemote('job_failed', self.job.job_id, msg)
-            d.addErrback(self._catch_failure)
-            self.restart()
-    
-    def job_done(self, output, result, completed):
-        """
-        job_done is a callback for doJob.  Called when a job completes.
+        except Exception, e:
+            print e
+            raise
+    
+    def jobDone(self, output, result, completed, worker_info):
+        r"""
+        jobDone is a callback for doJob.  Called when a job completes.
         
         Parameters:
@@ -138,18 +140,21 @@
         result -- the result of processing the job, a pickled object
         completed -- whether or not the job is completely finished (bool)
+        worker_info -- user@host, os.uname() (tuple)
         
         """
         
         try:
-            d = self.remoteobj.callRemote('job_done',
-                                          self.job.job_id,
+            d = self.remoteobj.callRemote('jobDone',
+                                          self.job.id,
                                           output,
                                           result,
-                                          completed)
+                                          completed,
+                                          worker_info)
         except Exception, msg:
             log.msg(msg)
-            log.msg('[Worker: %s, job_done] Disconnected, reconnecting in %s'\
-                    % (self.id, self.delay))
-            reactor.callLater(self.delay, self.job_done, output, result, completed)
+            log.msg('[Worker: %s, jobDone] Disconnected, reconnecting in %s'\
+                    % (self.id, DELAY))
+            reactor.callLater(DELAY, self.jobDone, output, 
+                              result, completed, worker_info)
             d = defer.Deferred()
             d.errback(error.ConnectionLost())
@@ -162,5 +167,7 @@
     
     def noJob(self, failure):
-        """
+        # TODO: Probably do not need this errback, look into consolidating 
+        # with failedJob
+        r"""
         noJob is an errback that catches the NoJobException.
         
@@ -172,24 +179,15 @@
         sleep_time = 5.0
         if failure.check(NoJobException):
-            if self.log_level > 3:
-                log.msg('[Worker %s, noJob] Sleeping for %s seconds' % (self.id, sleep_time))
-            reactor.callLater(sleep_time, self.get_job)
-        else:
-            print "Error: ", failure.getErrorMessage()
-            print "Traceback: ", failure.printTraceback()
-    
-    def setup_tmp_dir(self, job):
-        """
-        Creates the temporary directory for the worker.
-        
-        """
-        
+            reactor.callLater(5.0, self.getJob)
+    
+    def setupTempDir(self, job):
+        # change to a temporary directory
         cur_dir = os.getcwd() # keep a reference to the current directory
         tmp_dir = os.path.join(DSAGE_DIR, 'tmp_worker_files')
-        tmp_job_dir = os.path.join(tmp_dir, job.job_id)
+        tmp_job_dir = os.path.join(tmp_dir, job.id)
+        self.tmp_job_dir = tmp_job_dir
         if not os.path.isdir(tmp_dir):
             os.mkdir(tmp_dir)
-        if not os.path.isdir(tmp_job_dir):
-            os.mkdir(tmp_job_dir)
+        os.mkdir(tmp_job_dir)
         os.chdir(tmp_job_dir)
         self.sage.eval("os.chdir('%s')" % tmp_job_dir)
@@ -197,6 +195,6 @@
         return tmp_job_dir
         
-    def extract_job_data(self, job):
-        """
+    def extractJobData(self, job):
+        r"""
         Extracts all the data that is in a job object.
         
@@ -204,39 +202,38 @@
         
         if isinstance(job.data, list):
-            if self.log_level > 2:
+            if LOG_LEVEL > 2:
                 log.msg('Extracting job data...')
-            try:
-                for var, data, kind in job.data:
-                    try:
-                        data = zlib.decompress(data)
-                    except Exception, msg:
-                        log.msg(msg)
-                        continue
-                    if kind == 'file':
-                        f = open(var, 'wb')
-                        f.write(data)
-                        f.close()
-                        if self.log_level > 2:
-                            log.msg('[Worker: %s] Extracted %s. ' % (self.id, f))
-                    if kind == 'object':
-                        fname = var + '.sobj'
-                        if self.log_level > 2:
-                            log.msg('Object to be loaded: %s' % fname)
-                        f = open(fname, 'wb')
-                        f.write(data)
-                        f.close()
-                        self.sage.eval("%s = load('%s')" % (var, fname))
-                        if self.log_level > 2:
-                            log.msg('[Worker: %s] Loaded %s' % (self.id, fname))
-            except Exception, msg:
-                log.err(msg)
-
-    def write_job_file(self, job):
-        """
+            for var, data, kind in job.data:
+                # Uncompress data
+                try:
+                    data = zlib.decompress(data)
+                except Exception, msg:
+                    log.msg(msg)
+                    continue
+                if kind == 'file':
+                    # Write out files to current dir
+                    f = open(var, 'wb')
+                    f.write(data)
+                    if LOG_LEVEL > 2:
+                        log.msg('[Worker: %s] Extracted %s. ' % (self.id, f))
+                if kind == 'object':
+                    # Load object into the SAGE worker
+                    fname = var + '.sobj'
+                    if LOG_LEVEL > 3:
+                        log.msg('Object to be loaded: %s' % fname)
+                    f = open(fname, 'wb')
+                    f.write(data)
+                    f.close()
+                    self.sage.eval("%s = load('%s')" % (var, fname))
+                    if LOG_LEVEL > 2:
+                        log.msg('[Worker: %s] Loaded %s' % (self.id, fname))
+
+    def writeJobFile(self, job):
+        r"""
         Writes out the job file to be executed to disk.
         
         """
-        
-        parsed_file = preparse_file(job.code, magic=False, do_time=False, ignore_prompts=False)
+        parsed_file = preparse_file(job.file, magic=False,
+                                    do_time=False, ignore_prompts=False)
 
         job_filename = str(job.name) + '.py'
@@ -249,5 +246,6 @@
         job_file.write(END)
         job_file.close()
-        if self.log_level > 2:
+        
+        if LOG_LEVEL > 2:
             log.msg('[Worker: %s] Wrote job file. ' % (self.id))
             
@@ -255,5 +253,5 @@
         
     def doJob(self, job):
-        """
+        r"""
         doJob is the method that drives the execution of a job.
         
@@ -263,19 +261,18 @@
         """
         
-        if self.log_level > 3:
-            log.msg('[Worker %s, doJob] Beginning job execution...' % (self.id))
-            
         self.free = False
         d = defer.Deferred()
         
-        self.tmp_job_dir = self.setup_tmp_dir(job)
-        self.extract_job_data(job)
-        
-        job_filename = self.write_job_file(job)
-
-        f = os.path.join(self.tmp_job_dir, job_filename)
+        tmp_job_dir = self.setupTempDir(job)
+        self.extractJobData(job)
+        
+        job_filename = self.writeJobFile(job)
+
+        f = os.path.join(tmp_job_dir, job_filename)
         self.sage._send("execfile('%s')" % (f))
-        if self.log_level > 2:
+        if LOG_LEVEL > 2:
             log.msg('[Worker: %s] File to execute: %s' % (self.id, f))
+        if LOG_LEVEL > 3:
+            log.msg('[Worker: %s] Called sage._send()' % (self.id))
         
         d.callback(True)
@@ -284,45 +281,22 @@
     
     def stop(self):
-        """
-        Stops the current worker and resets it's internal state.
+        r"""
+        stop() kills the current running job.
             
         """
-        
-        INTERRUPT_TRIES = 10
-        timeout = 0.05
-        for i in range(INTERRUPT_TRIES):    
-            try: 
-                self.sage._expect.sendline(chr(3))  # send ctrl-c            
-                self.sage._expect.expect(self.sage._prompt, timeout=timeout)            
-                self.sage._expect.expect(self.sage._prompt, timeout=timeout)
-                success = True
-                break
-            except (pexpect.TIMEOUT, pexpect.EOF), msg:
-                if self.log_level > 3:
-                    log.err("Trying again to interrupt SAGE (try %s)..." % i)
-        
-        self.sage.reset()
+    
+        self.sage.quit()
         self.free = True
         self.job = None
+        self.sage = None
     
     def start(self):
-        """
-        Starts a new worker if it does not exist already.
-        
-        """
-        
-        if self.sage is None:
-            if self.log_level > 3:
-                self.sage = Sage(logfile=DSAGE_DIR + '/%s-pexpect.out' % self.id)
-            else:
-                self.sage = Sage()
-        self.get_job()
+        if LOG_LEVEL > 3:
+            self.sage = Sage(logfile=DSAGE_DIR + '/%s-pexpect.out' % self.id)
+        else:
+            self.sage = Sage()
+        self.getJob()
     
     def restart(self):
-        """
-        Restarts the current worker.
-        
-        """
-        
         log.msg('[Worker: %s] Restarting...' % (self.id))
         self.stop()
@@ -330,5 +304,5 @@
 
 class Monitor(object):
-    """
+    r"""
     This class represents a monitor that controls workers.
     
@@ -341,58 +315,21 @@
     """
     
-    def __init__(self, server, port):
-        self.conf = get_conf('monitor')
-        self.uuid = self.conf['id']
-        self.workers = int(self.conf['workers'])
-        self.log_file = self.conf['log_file']
-        self.log_level = self.conf['log_level']
-        self.delay = float(self.conf['delay'])
-        self.anonymous = get_bool(self.conf['anonymous'])
-        self.ssl = get_bool(self.conf['ssl'])
-        if server is None:
-            self.server = self.conf['server']
-        else:
-            self.server = server
-        if port is None:
-            if self.server == 'localhost':
-                self.port = int(get_conf('server')['client_port'])
-            else:
-                self.port = int(self.conf['port'])
-        else:
-            self.port = port
+    def __init__(self, hostname, port):
+        self.hostname = hostname
+        self.port = port
         self.remoteobj = None
         self.connected = False
         self.reconnecting = False
-        self.worker_pool = None
-
-        self.host_info = ClassicHostInfo().host_info
-        self.host_info['uuid'] = self.uuid
-        self.host_info['workers'] = self.workers
-        
-        self._startLogging(self.log_file)
-        
-        if not self.anonymous:
-            from twisted.cred import credentials
-            from twisted.conch.ssh import keys
-            self._get_auth_info()
-            # public key authentication information
-            self.pubkey_str =keys.getPublicKeyString(filename=self.pubkey_file)
-            # try getting the private key object without a passphrase first
-            try:
-                self.priv_key = keys.getPrivateKeyObject(filename=self.privkey_file)
-            except keys.BadKeyError:
-                pphrase = self._getpassphrase()
-                self.priv_key = keys.getPrivateKeyObject(filename=self.privkey_file,
-                                                         passphrase=pphrase)
-            self.pub_key = keys.getPublicKeyObject(self.pubkey_str)
-            self.alg_name = 'rsa'
-            self.blob = keys.makePublicKeyBlob(self.pub_key)
-            self.data = self.DATA
-            self.signature = keys.signData(self.priv_key, self.data)
-            self.creds = credentials.SSHPrivateKey(self.username,
-                                                   self.alg_name,
-                                                   self.blob, 
-                                                   self.data,
-                                                   self.signature)
+        self.workers = None
+        
+        # Start twisted logging facility
+        self._startLogging(LOG_FILE)
+        
+        if len(config.get('uuid', 'id')) != 36:
+            config.set('uuid', 'id', str(uuid.uuid1()))
+            f = open(conf_file, 'w')
+            config.write(f)
+        
+        self.identifier = config.get('uuid', 'id')
     
     def _startLogging(self, log_file):
@@ -403,29 +340,5 @@
             server_log = open(log_file, 'a')
             log.startLogging(server_log)
-
-    def _get_auth_info(self):
-        import random
-        self.DATA =  ''.join([chr(i) for i in [random.randint(65, 123) for n in
-                        range(500)]])
-        self.DSAGE_DIR = os.path.join(os.getenv('DOT_SAGE'), 'dsage')
-        # Begin reading configuration
-        try:
-            conf_file = os.path.join(self.DSAGE_DIR, 'client.conf')
-            config = ConfigParser.ConfigParser()
-            config.read(conf_file)
-            
-            self.username = config.get('auth', 'username')
-            self.privkey_file = os.path.expanduser(config.get('auth', 'privkey_file'))
-            self.pubkey_file = os.path.expanduser(config.get('auth', 'pubkey_file'))
-        except Exception, msg:
-            print msg
-            raise
-    
-    def _getpassphrase(self):
-        import getpass
-        passphrase = getpass.getpass('Passphrase (Hit enter for None): ')
-        
-        return passphrase
-        
+    
     def _connected(self, remoteobj):
         self.remoteobj = remoteobj
@@ -434,22 +347,20 @@
         self.reconnecting = False
         
-        if self.worker_pool == None: # Only pool workers the first time
-            self.pool_workers(self.remoteobj)
-        else:
-            for worker in self.worker_pool:
+        if self.workers == None: # Only pool workers the first time
+            self.poolWorkers(self.remoteobj)
+        else:
+            for worker in self.workers:
                 worker.remoteobj = self.remoteobj # Update workers
-        # self.submit_host_info()
+        self.submitHostInfo()
     
     def _disconnected(self, remoteobj):
-        log.err('Lost connection to the server.')
+        log.msg('Lost connection to the server.')
         self.connected = False
         self._retryConnect()
     
-    def _got_killed_jobs(self, killed_jobs):
+    def _gotKilledJobsList(self, killed_jobs):
         if killed_jobs == None:
             return
-        # reconstruct the Job objects from the jdicts
-        killed_jobs = [expand_job(jdict) for jdict in killed_jobs]
-        for worker in self.worker_pool:
+        for worker in self.workers:
             if worker.job is None:
                 continue
@@ -457,32 +368,29 @@
                 continue
             for job in killed_jobs:
-                if job is None or worker.job is None:
+                if job == None or worker.job == None:
                     continue
-                if worker.job.job_id == job.job_id:
-                    log.msg('[Worker: %s] Processing a killed job, restarting...' % worker.id)
+                job = unpickle(job)
+                if worker.job.id == job.id:
+                    log.msg('[Worker: %s] Processing a killed job, \
+                            restarting...' % worker.id)
                     worker.restart()
     
     def _retryConnect(self):
-        log.err('[Monitor] Disconnected, reconnecting in %s' % self.delay)
-        reactor.callLater(self.delay, self.connect)
+        log.msg('[Monitor] Disconnected, reconnecting in %s' % DELAY)
+        reactor.callLater(DELAY, self.connect)
     
     def _catchConnectionFailure(self, failure):
         # If we lost the connection to the server somehow
-        # if failure.check(error.ConnectionRefusedError,
+        #if failure.check(error.ConnectionRefusedError,
         #                 error.ConnectionLost,
         #                 pb.DeadReferenceError):
-        
         self.connected = False
         self._retryConnect()
-        
-        log.err("Error: ", failure.getErrorMessage())
-        log.err("Traceback: ", failure.printTraceback())
-    
-    def _catch_failure(self, failure):
-        log.err("Error: ", failure.getErrorMessage())
-        log.err("Traceback: ", failure.printTraceback())
-        
+        # else:
+       #      log.msg("Error: ", failure.getErrorMessage())
+       #      log.msg("Traceback: ", failure.printTraceback())
+    
     def connect(self):
-        """
+        r"""
         This method connects the monitor to a remote PB server. 
         
@@ -493,42 +401,29 @@
         factory = pb.PBClientFactory()
         
-        log.msg(DELIMITER)
-        log.msg('DSAGE Worker')
-        log.msg('PID %s'%os.getpid())
-        log.msg('Connecting to %s:%s' % (self.server, self.port))
-        log.msg(DELIMITER)
-        
-        self.factory = PBClientFactory()
-        if self.ssl == 1:
+        if SSL == 1:
             from twisted.internet import ssl
             contextFactory = ssl.ClientContextFactory()
-            reactor.connectSSL(self.server, self.port,
-                               self.factory, contextFactory) 
-        else:
-            reactor.connectTCP(self.server, self.port, self.factory)
-        
-        if not self.anonymous:
-            log.msg('Connecting as authenticated worker...\n')
-            d = self.factory.login(self.creds, (pb.Referenceable(), self.host_info))
-        else:
-            log.msg('Connecting as anonymous worker...\n')
-            d = self.factory.login('Anonymous', (pb.Referenceable(), self.host_info))
+            reactor.connectSSL(self.hostname, self.port, 
+                               factory, contextFactory)
+        else:
+            reactor.connectTCP(self.hostname, self.port, factory)
+        
+        d = factory.getRootObject()
         d.addCallback(self._connected)
         d.addErrback(self._catchConnectionFailure)
-            
         return d
     
-    def pool_workers(self, remoteobj):
-        """
-        pool_workers creates as many workers as specified in worker.conf. 
-        
-        """
-        
-        log.msg('[Monitor] Starting %s workers...' % (self.workers))
-        self.worker_pool = [Worker(remoteobj, x) for x in range(self.workers)]
-    
-    def check_output(self):
-        """
-        check_output periodically polls workers for new output.
+    def poolWorkers(self, remoteobj):
+        r"""
+        poolWorkers creates as many workers as specified in worker.conf. 
+        
+        """
+        
+        self.workers = [Worker(remoteobj, x) for x in range(WORKERS)]
+        log.msg('Initialized ' + str(len(self.workers)) + ' workers.')
+    
+    def checkForJobOutput(self):
+        r"""
+        checkForJobOutput periodically polls workers for new output.
         
         This figures out whether or not there is anything new output that we
@@ -537,8 +432,8 @@
         """
 
-        if self.worker_pool == None:
+        if self.workers == None:
             return
         
-        for worker in self.worker_pool:
+        for worker in self.workers:
             if worker.job == None:
                 continue
@@ -546,59 +441,59 @@
                 continue
             
-            if self.log_level > 1:
-                log.msg('[Monitor] Checking for job output of worker %s' % (worker.id))
+            # log.msg('[Monitor] Checking for job output')
             try:
                 done, output, new = worker.sage._so_far()
             except Exception, msg:
-                log.err('Exception raised when checking output.')
-                log.err(msg)
+                log.msg(msg)
                 continue
             if new == '' or new.isspace():
                 continue
             if done:
-                worker.free = True
+                # Checks to see if the job created a result var
                 sobj = worker.sage.get('DSAGE_RESULT')
-                timeout = 0.1
-                while sobj == '' or sobj.isspace():
+                if sobj == '' or sobj.isspace():
+                    if LOG_LEVEL > 1:
+                        log.msg('Something went wrong, it should not be empty.')
+                    worker.sage._get()
                     sobj = worker.sage.get('DSAGE_RESULT')
-                    time.sleep(timeout)
-                if 'NameError: name \'DSAGE_RESULT\' is not defined' in sobj:
-                    if self.log_level > 1:
+                    if sobj == '' or sobj.isspace():
+                        worker.sage._get()
+                        sobj = worker.sage.get('DSAGE_RESULT')
+                    else:
+                        if LOG_LEVEL > 1:
+                            log.msg('Got DSAGE_RESULT second time')
+                
+                # DSAGE_RESULT does not exist
+                if 'Traceback' in sobj or 'NameError' in sobj:
+                    if LOG_LEVEL > 1:
                         log.msg('DSAGE_RESULT does not exist')
                     result = cPickle.dumps('No result saved.', 2)
                 else:
+                    os.chdir(worker.tmp_job_dir)
                     try:
-                        os.chdir(worker.tmp_job_dir)
-                        worker.sage.eval("os.chdir('%s')" % (worker.tmp_job_dir))
-                        worker.sage.eval("save(DSAGE_RESULT, 'result', compress=True)")
-                        result = open('result.sobj', 'rb').read() # Already in compressed form.
+                        result = open(sobj, 'rb').read()
                     except Exception, msg:
-                        if self.log_level > 1:
-                            log.err(msg)
-                        result = cPickle.dumps(msg, 2)
-                log.msg("[Worker: %s] Job '%s' finished" % (worker.id, worker.job.job_id))
+                        if LOG_LEVEL > 1:
+                            log.msg(msg)
+                        result = cPickle.dumps('Error in reading result.', 2)
+                worker.free = True
+                log.msg("Job '%s' finished" % worker.job.name)
             else:
-                result = cPickle.dumps('Job not done yet.', 2)
-                                       
-            sanitized_output = self.clean_output(new)
-            if self.check_failure(sanitized_output):
-                s = ['[Monitor] Error in result for ',
-                     '%s:%s ' % (worker.job.name, worker.job.job_id),
-                     'Worker ID:%s' % (worker.id)]
-                log.err(''.join(s))
-                log.err('[Monitor] Traceback: \n%s' % sanitized_output)
-                d = self.remoteobj.callRemote('job_failed', worker.job.job_id, sanitized_output)
-                d.addErrback(self._catch_failure)
-                worker.restart()
-                continue
-            d = worker.job_done(sanitized_output, result, done)
+                result = 'No result yet.'
+            
+            worker_info = (os.getenv('USER') + '@' + os.uname()[1],
+                           ' '.join(os.uname()[2:]))
+            sanitized_output = self.sanitizeOutput(new)
+            
+            if self.checkOutputForFailure(sanitized_output):
+                log.msg('[Monitor] Error in result for job %s %s done by \
+Worker: %s ' % (worker.job.name, worker.job.id, worker.id))
+                log.msg('[Monitor] Traceback: \n%s' % sanitized_output)
+                d = self.remoteobj.callRemote('jobFailed', worker.job.id)
+                
+            d = worker.jobDone(sanitized_output, result, done, worker_info)
             d.addErrback(self._catchConnectionFailure)
     
-    def check_failure(self, sage_output):
-        """
-        Checks for signs of exceptions or errors in the output.
-        
-        """
-        
+    def checkOutputForFailure(self, sage_output):
         if sage_output == None:
             return False
@@ -613,7 +508,7 @@
             return False
     
-    def check_killed_jobs(self):
-        """
-        check_killed_jobs retrieves a list of killed job ids.
+    def checkForKilledJobs(self):
+        r"""
+        checkForKilledJobs retrieves a list of killed job ids.
         
         """
@@ -621,15 +516,28 @@
         if not self.connected:
             return
-            
-        killed_jobs = self.remoteobj.callRemote('get_killed_jobs_list')
-        killed_jobs.addCallback(self._got_killed_jobs)
-        killed_jobs.addErrback(self._catch_failure)
-    
-    def clean_output(self, sage_output):
-        """
-        clean_output attempts to clean up the output string from sage. 
-        
-        """
-        
+        # try:
+        killed_jobs = self.remoteobj.callRemote('getKilledJobsList')
+#        except:
+#            if not self.reconnecting:
+#                self._retryConnect()
+#            return
+        killed_jobs.addCallback(self._gotKilledJobsList)
+    
+    def jobUpdated(self, id):
+        r"""
+        jobUpdated is a callback that gets called when there is new output
+        from checkForJobOutput.
+        
+        """
+        
+        print str(id) + ' was updated!'
+    
+    def sanitizeOutput(self, sage_output):
+        r"""
+        sanitizeOutput attempts to clean up the output string from sage. 
+        
+        """
+        
+        # log.msg("Before cleaning output: ", sage_output)
         begin = sage_output.find(START_MARKER)
         if begin != -1:
@@ -646,60 +554,75 @@
         output = output.replace('\r', '')
         
+        # log.msg("After cleaning output: ", output)
         return output
     
-    def start_looping_calls(self):
-        """
-        start_looping_calls prepares and starts our periodic checking methods.
-        
-        """
-        
-        self.tsk1 = task.LoopingCall(self.check_output)
+    def _gotHostInfo(self, h):
+        
+        # attach the workers uuid to the dictionary returned by
+        # HostInfo().get_host_info
+        h['uuid'] = self.identifier
+        
+        d = self.remoteobj.callRemote("submitHostInfo", h)
+        d.addErrback(self._catchConnectionFailure)
+        log.msg('Submitted host info')
+    
+    def submitHostInfo(self):
+        r"""
+        Sends the workers hardware specs to the server. 
+        
+        """
+        
+        h = HostInfo().get_host_info()
+        h.addCallback(self._gotHostInfo)
+        h.addErrback(self._catchConnectionFailure)
+    
+    def startLoopingCalls(self):
+        r"""
+        startLoopingCalls prepares and starts our periodic checking methods.
+        
+        """
+    
+        # submits the output to the server
+        self.tsk1 = task.LoopingCall(self.checkForJobOutput)
         self.tsk1.start(0.1, now=False)
-        interval = 5.0
-        self.tsk2 = task.LoopingCall(self.check_killed_jobs)
-        self.tsk2.start(interval, now=False)
-    
-    def stop_looping_calls(self):
-        """
-        stops the looping calls. 
-        
-        """
-        
+        
+        # checks for killed jobs
+        self.tsk2 = task.LoopingCall(self.checkForKilledJobs)
+        self.tsk2.start(5.0, now=False)
+    
+    def stopLoopingCalls(self):
+        r"""
+        Stops the looping calls. 
+        
+        """
+        self.tsk.stop()
         self.tsk1.stop()
         self.tsk2.stop()
 
 def main():
-    """
+    r"""
     argv[1] == hostname
     argv[2] == port
     
     """
-
+    
+    if len(sys.argv) == 1:
+        monitor = Monitor(SERVER, PORT)
+    if len(sys.argv) == 2:
+        monitor = Monitor(sys.argv[1], PORT)
     if len(sys.argv) == 3:
-        hostname, port = sys.argv[1:3]        
         try:
-            port = int(port)
-        except:
-            port = None
-        if hostname == 'None':
-            hostname = None
-        else:
-            try:
-                hostname = str(hostname)
-            except Exception, msg:
-                print msg
-                hostname = None
-    else:
-        hostname = port = None
-        
-    monitor = Monitor(hostname, port)
+            port = int(sys.argv[2])
+        except Exception, e:
+            print e
+            port = PORT
+        monitor = Monitor(sys.argv[1], port)
 
     monitor.connect()
-    monitor.start_looping_calls()
-    
+    monitor.startLoopingCalls()
     try:
         reactor.run()
     except:
-        sys.exit()
+        sys.exist(-1)
 
 if __name__ == '__main__':
Index: sage/dsage/server/client_tracker.py
===================================================================
--- sage/dsage/server/client_tracker.py	(revision 3866)
+++ sage/dsage/server/client_tracker.py	(revision 2942)
@@ -20,5 +20,5 @@
 
 def add(avatar):
-    """
+    r"""
     Adds an avatar to clients_list. 
     
@@ -28,5 +28,5 @@
 
 def remove(avatar):
-    """
+    r"""
     Removes the avatar from the client_list.
     
Index: sage/dsage/server/server.py
===================================================================
--- sage/dsage/server/server.py	(revision 3895)
+++ sage/dsage/server/server.py	(revision 3600)
@@ -19,7 +19,4 @@
 import zlib
 import cPickle
-import datetime
-import xml.dom.minidom
-import cStringIO
 
 from twisted.spread import pb
@@ -27,12 +24,13 @@
 
 from sage.dsage.misc.hostinfo import HostInfo
+import sage.dsage.server.worker_tracker as worker_tracker
+import sage.dsage.server.client_tracker as client_tracker
 from sage.dsage.server.hostinfo_tracker import hostinfo_list
 from sage.dsage.errors.exceptions import BadTypeError
-from sage.dsage.database.job import expand_job
 
 pb.setUnjellyableForClass(HostInfo, HostInfo)
 
 class DSageServer(pb.Root):
-    """
+    r"""
     This class represents Distributed Sage server which does all the 
     coordination of distributing jobs, creating new jobs and accepting job 
@@ -40,7 +38,6 @@
         
     """
-    
-    def __init__(self, jobdb, monitordb, clientdb, log_level=0):
-        """
+    def __init__(self, jobdb, log_level=0):
+        r"""
         Initializes the Distributed Sage PB Server.
 
@@ -52,13 +49,11 @@
 
         self.jobdb = jobdb
-        self.monitordb = monitordb
-        self.clientdb = clientdb
-        self.LOG_LEVEL = log_level
+        self.log_level = log_level
 
     def unpickle(self, pickled_job):
         return cPickle.loads(zlib.decompress(pickled_job))
 
-    def get_job(self, anonymous=False):
-        """
+    def getJob(self):
+        r"""
         Returns a job to the client.
         
@@ -68,28 +63,20 @@
         """
         
-        if anonymous:
-            jdict = self.jobdb.get_job(anonymous=True)
-        else:
-            jdict = self.jobdb.get_job(anonymous=False)
-        if jdict == None:
-            if self.LOG_LEVEL > 3:
-                log.msg('[DSage, get_job]' + ' Job db is empty.')
+        job = self.jobdb.getJob()
+    
+        if job == None:
+            if self.log_level > 2:
+                log.msg('[DSage]' + ' Job db is empty.')
             return None
         else:
-            if self.LOG_LEVEL > 3:
-                log.msg('[DSage, get_job]' + ' Returning Job %s to client' % (jdict['job_id']))
-            jdict['status'] = 'processing'
-            jdict = self.jobdb.store_job(jdict)
-            
-        return jdict
-    
-    def set_job_uuid(self, job_id, uuid):
-        return self.jobdb.set_job_uuid(job_id, uuid)
-    
-    def set_busy(self, uuid, busy):
-        return self.monitordb.set_busy(uuid, busy=busy)
-        
-    def get_job_by_id(self, job_id):
-        """
+            if self.log_level > 3:
+                log.msg('[DSage, getJob]' + ' Returning Job (%s, %s) to client' 
+                % (job.id, job.name))
+            job.status = 'processing'
+            self.jobdb.storeJob(job)
+        return job.pickle()
+
+    def getJobByID(self, jobID):
+        r"""
         Returns a job by the job id. 
         
@@ -99,11 +86,8 @@
         """
 
-        jdict = self.jobdb.get_job_by_id(job_id)
-        uuid = jdict['monitor_id']
-        jdict['worker_info'] = self.monitordb.get_monitor(uuid)
-        
-        return jdict
-
-    def get_job_result_by_id(self, job_id):
+        job = self.jobdb.getJobByID(jobID)
+        return job.pickle()
+
+    def getJobResultByID(self, jobID):
         """Returns the job result.
 
@@ -113,10 +97,8 @@
         """
         
-        jdict = self.jobdb.get_job_by_id(job_id)
-        job = expand_job(jdict)
-        
+        job = self.jobdb.getJobByID(jobID)
         return job.result
 
-    def get_job_output_by_id(self, job_id):
+    def getJobOutputByID(self, jobID):
         """Returns the job output.
 
@@ -126,72 +108,77 @@
         """
 
-        job = self.jobdb.get_job_by_id(job_id)
+        job = self.jobdb.getJobByID(jobID)
 
         return job.output
 
-    def sync_job(self, job_id):
-        raise NotImplementedError
-        # job = self.jobdb.get_job_by_id(job_id)
+    def syncJob(self, jobID):
+        job = self.jobdb.getJobByID(jobID)
         # new_job = copy.deepcopy(job)
         # print new_job
         # # Set file, data to 'Omitted' so we don't need to transfer it 
-        # new_job.code = 'Omitted...'
+        # new_job.file = 'Omitted...'
         # new_job.data = 'Omitted...'
 
-        # return job.pickle()
-
-    def get_jobs_by_username(self, username, active=False):
-        """
-        Returns jobs created by username. 
-
-        Parameters:
-        username -- the username (str)
-        active -- when set to True, only return active jobs (bool)
+        return job.pickle()
+
+    def getJobsByAuthor(self, author, is_active, job_name):
+        r"""
+        Returns jobs created by author. 
+
+        Parameters:
+        author -- the author name (str)
+        is_active -- when set to True, only return active jobs (bool)
         job_name -- the job name (optional)
 
         """
 
-        jobs = self.jobdb.get_jobs_by_username(username, active)
-        
-        if self.LOG_LEVEL > 3:
+        jobs = self.jobdb.getJobsByAuthor(author, is_active, job_name)
+        
+        if self.log_level > 3:
             log.msg(jobs)
         return jobs
 
-    def submit_job(self, jdict):
-        """
+    def submitJob(self, pickled_job):
+        r"""
         Submits a job to the job database.
         
         Parameters:
-        jdict -- the internal dictionary of a Job object
+        pickled_job -- a pickled_Job object
         
         """ 
         
-
-        if self.LOG_LEVEL > 3:
-            log.msg('[DSage, submit_job] %s' % (jdict))
-        
-        if jdict['code'] is None:
+        try:
+            if self.log_level > 3:
+                log.msg('[DSage, submitJob] Trying to unpickle job')
+            job = self.unpickle(pickled_job)
+        except:
             return False
-        if jdict['name'] is None:
-            jdict['name'] = 'Default'
-        jdict['update_time'] = datetime.datetime.now()
-        
-        return self.jobdb.store_job(jdict)
-        
-    def get_all_jobs(self):
-        """
-        Returns a list of all jobs in the database. 
-        
-        """
-        return self.jobdb.get_all_jobs()
-        
-    def get_active_jobs(self):
-        """
+        if job.file is None:
+            return False
+        if job.name is None:
+            job.name = 'defaultjob'
+        if job.id is None:
+            job.id = self.jobdb.getJobID()
+            
+        if self.log_level > 0:
+            log.msg('[DSage, submitJob] Job (%s %s) submitted' % (job.id, 
+                                                                 job.name))
+        return self.jobdb.storeJob(job)
+
+    def getJobsList(self):
+        r"""
+        Returns an ordered list of jobs in the database. 
+        
+        """
+        return self.jobdb.getJobsList()
+
+    def getActiveJobs(self):
+        r"""
         Returns a list of active jobs"""
 
-        return self.jobdb.get_active_jobs()
-
-    def get_active_clients_list(self):
-        """
+        return self.jobdb.getActiveJobs()
+
+    def getActiveClientList(self):
+        r"""
         Returns a list of active clients.
         
@@ -200,83 +187,82 @@
         raise NotImplementedError
 
-    def get_killed_jobs_list(self):
-        """
-        Returns a list of killed job jdicts. 
-        """
-        
-        killed_jobs = self.jobdb.get_killed_jobs_list()
-        return killed_jobs
-
-    def get_next_job_id(self):
-        """
+    def getKilledJobsList(self):
+        r"""
+        Returns a list of killed jobs. 
+        """
+        
+        killed_jobs = self.jobdb.getKilledJobsList()
+        return [job.pickle() for job in killed_jobs]
+
+    def getNextJobID(self):
+        r"""
         Returns the next job id.
         
         """
         
-        if self.LOG_LEVEL > 0:
-            log.msg('[DSage, get_next_job_id] Returning next job ID')
+        if self.log_level > 0:
+            log.msg('[DSage, getNextJobID] Returning next job ID')
             
-        return self.jobdb.get_next_job_id()
-
-    def job_done(self, job_id, output, result, completed):
-        """
-        job_done is called by the workers check_output method.
-
-        Parameters:
-        job_id -- job id (str)
+        return self.jobdb.getJobID()
+
+    def jobDone(self, jobID, output, result, completed, worker_info):
+        r"""
+        jobDone is called by the workers checkForJobOutput method.
+
+        Parameters:
+        jobID -- job id (str)
         output -- the stdout from the worker (string)
         result -- the result from the client (compressed pickle string)
                   result could be 'None'
         completed -- whether or not the job is completed (bool)
-
-        """
-
-        if self.LOG_LEVEL > 0:
-            log.msg('[DSage, job_done] Job %s called back' % (job_id))
-        if self.LOG_LEVEL > 3:
-            log.msg('[DSage, job_done] Output: %s ' % output)
-            log.msg('[DSage, job_done] completed: %s ' % completed)
-
-        jdict = self.get_job_by_id(job_id)
+        worker_info -- ''.join(os.uname())
+
+        """
+
+        if self.log_level > 0:
+            log.msg('[DSage, jobDone] Job %s called back' % (jobID))
+        if self.log_level > 2:
+            log.msg('[DSage, jobDone] Output: %s ' % output)
+            log.msg('[DSage, jobDone] Result: Some binary data...')
+            log.msg('[DSage, jobDone] completed: %s ' % completed)
+            log.msg('[DSage, jobDone] worker_info: %s ' % str(worker_info))
+
+        job = self.unpickle(self.getJobByID(jobID))
+
+        if self.log_level > 3:
+            log.msg('[DSage, jobDone] result type' , type(result))
+            
         output = str(output)
-        if jdict['output'] is not None: # Append new output to existing output
-            jdict['output'] += output
+        if job.output is not None: # Append new output to existing output
+            job.output = job.output + output
         else:
-            jdict['output'] = output
+            job.output = output
         if completed:
-            jdict['result'] = result
-            jdict['status'] = 'completed'
-        
-        jdict['update_time'] = datetime.datetime.now()
-
-        return self.jobdb.store_job(jdict)
-
-    def job_failed(self, job_id, traceback):
-        """
-        job_failed is called when a remote job fails.
-
-        Parameters:
-        job_id -- the job id (str)
+            job.result = result
+            job.status = 'completed'
+            job.worker_info = worker_info
+
+        return self.jobdb.storeJob(job)
+
+    def jobFailed(self, jobID):
+        r"""
+        jobFailed is called when a remote job fails.
+
+        Parameters:
+        jobID -- the job id (str)
         
         """
     
-        job = expand_job(self.jobdb.get_job_by_id(job_id))
+        job = self.jobdb.getJobByID(jobID)
         job.failures += 1
-        job.output = traceback
-        
-        if job.failures > self.jobdb.job_failure_threshold:
-            job.status = 'failed'
-        else:
-            job.status = 'new' # Put job back in the queue
-        
-        if self.LOG_LEVEL > 1:
-            s = ['[DSage, job_failed] Job %s failed ' % (job_id),
-                 '%s times. ' % (job.failures)]
-            log.msg(''.join(s))
-            
-        return self.jobdb.store_job(job.reduce())
-
-    def kill_job(self, job_id, reason):
-        """
+        job.status = 'new' # Put job back in the queue
+        
+        if self.log_level > 1:
+            log.msg('[DSage, jobFailed] Job %s failed' % jobID)
+        
+        self.jobdb.storeJob(job)
+
+    def killJob(self, jobID, reason):
+        r"""
         Kills a job.  
 
@@ -285,17 +271,19 @@
         """
 
-        if job_id == None:
-            if self.LOG_LEVEL > 0:
-                log.msg('[DSage, kill_job] No such job id %s' % job_id)
+        job = self.unpickle(self.getJobByID(jobID))
+        if job == None:
+            if self.log_level > 0:
+                log.msg('[DSage, killJob] No such job id')
             return None
         else:
-            self.jobdb.set_killed(job_id, killed=True)
-            if self.LOG_LEVEL > 0:
-                log.msg('Killed job %s' % (job_id))
+            job.killed = True
+            self.jobdb.storeJob(job)
+            if self.log_level > 0:
+                log.msg('Job %s was killed because %s ' % (jobID, reason))
                 
-        return job_id
-
-    def get_monitor_list(self):
-        """
+        return jobID
+
+    def getWorkerList(self):
+        r"""
         Returns a list of workers as a 3 tuple.
 
@@ -305,16 +293,17 @@
 
         """
-        return self.monitordb.get_monitor_list()
+
+        return worker_tracker.worker_list
     
-    def get_client_list(self):
-        """
+    def getClientList(self):
+        r"""
         Returns a list of clients.
         
         """
         
-        return self.clientdb.get_client_list()
-
-    def get_cluster_speed(self):
-        """
+        return client_tracker.client_list
+
+    def getClusterSpeed(self):
+        r"""
         Returns an approximation of the total CPU speed of the cluster.
 
@@ -322,5 +311,5 @@
         
         cluster_speed = 0
-        if self.LOG_LEVEL > 3:
+        if self.log_level > 3:
             log.msg(hostinfo_list)
             log.msg(len(hostinfo_list))
@@ -332,27 +321,12 @@
         
         return cluster_speed
-    
-    def get_worker_count(self):
-        """
-        Returns a list of busy and free workers.
-        
-        """
-        
-        count = {}
-        free_workers = self.monitordb.get_worker_count(connected=True, busy=False)
-        working_workers = self.monitordb.get_worker_count(connected=True, busy=True)
-        
-        count['free'] = free_workers
-        count['working'] = working_workers
-        
-        return count
-        
-    def submit_host_info(self, h):
-        """
+
+    def submitHostInfo(self, h):
+        r"""
         Takes a dict of workers machine specs. 
         
         """
         
-        if self.LOG_LEVEL > 0:
+        if self.log_level > 0:
             log.msg(h)
         if len(hostinfo_list) == 0:
@@ -362,225 +336,35 @@
                 if h['uuid'] not in h.values():
                     hostinfo_list.append(h)
-    
-    def generate_xml_stats(self):
-        """
-        This method returns a an XML document to be consumed by the Dashboard
-        widget
-        
-        """
-        
-        def create_gauge(doc):
-            gauge = doc.createElement('gauge')
-            doc.appendChild(gauge)
-
-            return doc, gauge
-
-        def add_totalAgentCount(doc, gauge):
-            totalAgentCount = doc.createElement('totalAgentCount')
-            gauge.appendChild(totalAgentCount)
-            working_workers = self.monitordb.get_worker_count(connected=True,
-                                                              busy=True)
-            free_workers = self.monitordb.get_worker_count(connected=True,
-                                                           busy=False)
-            disconnected_workers = self.monitordb.get_worker_count(
-                                   connected=False,
-                                   busy=False)
-            total_workers = (working_workers + 
-                             free_workers + 
-                             disconnected_workers)
-            count = doc.createTextNode(str(total_workers))
-            totalAgentCount.appendChild(count)
-
-            return doc, totalAgentCount
-        
-        def add_onlineAgentCount(doc, gauge):
-            onlineAgentCount = doc.createElement('onlineAgentCount')
-            gauge.appendChild(onlineAgentCount)
-            free_workers = self.monitordb.get_worker_count(connected=True,
-                                                           busy=False)
-            busy_workers = self.monitordb.get_worker_count(connected=True,
-                                                           busy=True)
-            count = doc.createTextNode(str(free_workers + busy_workers))
-            onlineAgentCount.appendChild(count)
-            
-            return doc, onlineAgentCount
-            
-        def add_offlineAgentCount(doc, gauge):
-            offlineAgentCount = doc.createElement('offlineAgentCount')
-            gauge.appendChild(offlineAgentCount)
-            worker_count = self.monitordb.get_worker_count(connected=False,
-                                                           busy=False)
-            count = doc.createTextNode(str(worker_count))
-            offlineAgentCount.appendChild(count)
-            
-            return doc, offlineAgentCount
-            
-        def add_workingAgentCount(doc, gauge):
-            workingAgentCount = doc.createElement('workingAgentCount')
-            gauge.appendChild(workingAgentCount)
-            worker_count = self.monitordb.get_worker_count(connected=True,
-                                                           busy=True)
-            count = doc.createTextNode(str(worker_count))
-            workingAgentCount.appendChild(count)
-            
-            return doc, workingAgentCount
-        
-        def add_availableAgentCount(doc, gauge):
-            availableAgentCount = doc.createElement('availableAgentCount')
-            gauge.appendChild(availableAgentCount)
-            worker_count = self.monitordb.get_worker_count(connected=True,
-                                                           busy=False)
-            count = doc.createTextNode(str(worker_count))
-            availableAgentCount.appendChild(count)
-            
-            return doc, availableAgentCount
-        
-        def add_unavailableAgentCount(doc, gauge):
-            unavailableAgentCount = doc.createElement('unavailableAgentCount')
-            gauge.appendChild(unavailableAgentCount)
-            worker_count = self.monitordb.get_worker_count(connected=True,
-                                                           busy=True)
-            count = doc.createTextNode(str(worker_count))
-            unavailableAgentCount.appendChild(count)
-            
-            return doc, unavailableAgentCount
-            
-        def add_workingMegaHertz(doc, gauge):
-            workingMegaHertz = doc.createElement('workingMegaHertz')
-            gauge.appendChild(workingMegaHertz)
-            cpu_speed = self.monitordb.get_cpu_speed(connected=True, busy=True)
-            mhz = doc.createTextNode(str(cpu_speed))
-            workingMegaHertz.appendChild(mhz)
-
-            return doc, workingMegaHertz
-
-        def add_availableProcessorCount(doc, gauge):
-            pass
-            
-        def add_unavailableProcessorCount(doc, gauge):
-            pass
-            
-        def add_onlineProcessorCount(doc, gauge):
-            onlineProcessorCount = doc.createElement('onlineProcessorCount')
-            gauge.appendChild(onlineProcessorCount)
-            cpu_count = self.monitordb.get_cpu_count(connected=True)
-            c = doc.createTextNode(str(cpu_count))
-            onlineProcessorCount.appendChild(c)
-            
-            return doc, onlineProcessorCount
-        
-        def add_offlineProcessorCount(doc, gauge):
-            offlineProcessorCount = doc.createElement('offlineProcessorCount')
-            gauge.appendChild(offlineProcessorCount)
-            cpu_count = self.monitordb.get_cpu_count(connected=False)
-            c = doc.createTextNode(str(cpu_count))
-            offlineProcessorCount.appendChild(c)
-            
-            return doc, offlineProcessorCount
-            
-        def add_workingProcessorCount(doc, gauge):
-            workingProcessorCount = doc.createElement('workingProcessorCount')
-            gauge.appendChild(workingProcessorCount)
-            worker_count = self.monitordb.get_cpu_count(connected=True)
-            pcount = doc.createTextNode(str(worker_count))
-            workingProcessorCount.appendChild(pcount)
-
-            return doc, workingProcessorCount
-        
-        def add_workingAgentPercentage(doc, gauge):
-            workingAgentPercentage = doc.createElement(
-                                                    'workingAgentPercentage')
-            gauge.appendChild(workingAgentPercentage)
-            working_workers = self.monitordb.get_worker_count(connected=True,
-                                                              busy=True)
-            free_workers = self.monitordb.get_worker_count(connected=True,
-                                                           busy=False)
-            disconnected_workers = self.monitordb.get_worker_count(
-                                   connected=False,
-                                   busy=False)
-            total_workers = (working_workers + 
-                             free_workers + 
-                             disconnected_workers)
-            
-            if total_workers != 0:
-                worker_percentage = float(working_workers / total_workers) * 100
-            else:
-                worker_percentage = 0.0
-            percentage = doc.createTextNode(str(worker_percentage))
-            workingAgentPercentage.appendChild(percentage)
-            
-            return doc, workingAgentPercentage
-            
-        def add_date(doc, gauge):
-            date = datetime.datetime.now()
-
-            year = doc.createElement('Year')
-            gauge.appendChild(year)
-            year.appendChild(doc.createTextNode(str(date.year)))
-
-            seconds = doc.createElement('Seconds')
-            gauge.appendChild(seconds)
-            seconds.appendChild(doc.createTextNode(str(date.second)))
-
-            minutes = doc.createElement('Minutes')
-            gauge.appendChild(minutes)
-            minutes.appendChild(doc.createTextNode(str(date.minute)))
-
-            return doc, year, seconds, minutes
-        
-        doc = xml.dom.minidom.Document()
-        doc, gauge = create_gauge(doc)
-        
-        add_totalAgentCount(doc, gauge)
-        add_onlineAgentCount(doc, gauge)
-        add_offlineAgentCount(doc, gauge)
-        add_availableAgentCount(doc, gauge)
-        add_unavailableAgentCount(doc, gauge)
-        add_workingAgentCount(doc, gauge)
-        add_workingAgentPercentage(doc, gauge)
-
-        add_onlineProcessorCount(doc, gauge)
-        add_offlineAgentCount(doc, gauge)
-        add_availableProcessorCount(doc, gauge)
-        add_unavailableProcessorCount(doc, gauge)
-        add_workingProcessorCount(doc, gauge)
-        add_workingMegaHertz(doc, gauge)
-        
-        add_date(doc, gauge)
-        s = cStringIO.StringIO()    
-        doc.writexml(s, newl='\n')
-        
-        return s.getvalue()
 
 class DSageWorkerServer(DSageServer):
-    """
+    r"""
     Exposes methods to workers. 
     """
     
-    def remote_get_job(self):
-        return DSageServer.get_job(self)
-
-    def remote_job_done(self, job_id, output, result, completed, worker_info):
-        if not (isinstance(job_id, str) or isinstance(completed, bool)):
-            log.msg('BadType in remote_job_done')
+    def remote_getJob(self):
+        return DSageServer.getJob(self)
+
+    def remote_jobDone(self, jobID, output, result, completed, worker_info):
+        if not (isinstance(jobID, str) or isinstance(completed, bool)):
+            log.msg('BadType in remote_jobDone')
             raise BadTypeError()
 
-        return DSageServer.job_done(self, job_id, output, result, 
+        return DSageServer.jobDone(self, jobID, output, result, 
                              completed, worker_info)
 
-    def remote_job_failed(self, job_id, traceback):
-        if not isinstance(job_id, str):
-            log.msg('BadType in remote_job_failed')
+    def remote_jobFailed(self, jobID):
+        if not isinstance(jobID, str):
+            log.msg('BadType in remote_jobFailed')
             raise BadTypeError()
             
-        return DSageServer.job_failed(self, job_id, traceback)
-
-    def remote_get_killed_jobs_list(self):
-        return DSageServer.get_killed_jobs_list(self)        
-
-    def remote_submit_host_info(self, hostinfo):
+        return DSageServer.jobFailed(self, jobID)
+
+    def remote_getKilledJobsList(self):
+        return DSageServer.getKilledJobsList(self)        
+
+    def remote_submitHostInfo(self, hostinfo):
         if not isinstance(hostinfo, dict):
-            log.msg('BadType in remote_submit_host_info')
+            log.msg('BadType in remote_submitHostInfo')
             raise BadTypeError()
-        return DSageServer.submit_host_info(self, hostinfo)
-
+        return DSageServer.submitHostInfo(self, hostinfo)
+
Index: age/dsage/server/tests/test_server.py
===================================================================
--- sage/dsage/server/tests/test_server.py	(revision 3866)
+++ 	(revision )
@@ -1,185 +1,0 @@
-############################################################################
-#                                                                     
-#   DSAGE: Distributed SAGE                     
-#                                                                             
-#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
-#                                                                            
-#  Distributed under the terms of the GNU General Public License (GPL)        
-#
-#    This code 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
-#    General Public License for more details.
-#
-#  The full text of the GPL is available at:
-#
-#                  http://www.gnu.org/licenses/
-############################################################################
-
-import unittest
-import datetime
-import os
-from glob import glob
-
-from sage.dsage.database.job import Job, expand_job
-from sage.dsage.database.jobdb import JobDatabaseSQLite
-from sage.dsage.database.monitordb import MonitorDatabase
-from sage.dsage.database.clientdb import ClientDatabase
-from sage.dsage.server.server import DSageServer
-
-class DSageServerTestCase(unittest.TestCase):
-    """
-    Tests for DSageServer go here.
-    
-    """
-        
-    def setUp(self):
-        self.jobdb = JobDatabaseSQLite(test=True)
-        self.monitordb = MonitorDatabase(test=True)
-        self.clientdb = ClientDatabase(test=True)
-        self.dsage_server = DSageServer(self.jobdb, 
-                                        self.monitordb,
-                                        self.clientdb,
-                                        log_level=5)
-        for job in self.create_jobs(10):
-            self.dsage_server.submit_job(job.reduce())
-            
-    def tearDown(self):
-        self.dsage_server.jobdb._shutdown()
-        files = glob('*.db*')
-        for file in files:
-            os.remove(file)
-
-    def testget_job(self):
-        jdict = self.dsage_server.get_job()
-        self.assertEquals(type(jdict), dict)
-        job = expand_job(jdict)
-        self.assert_(isinstance(job, Job))
-
-    def testget_job_by_id(self):
-        job = Job()
-        job.code = '2+2'
-        jdict = self.dsage_server.submit_job(job.reduce())
-        self.assertEquals(type(jdict['job_id']), str)
-
-    def testget_job_result_by_id(self):
-        job = self.create_jobs(1)[0]
-        job = expand_job(self.dsage_server.get_job())
-        job.result = 'test'
-        jdict = self.dsage_server.submit_job(job.reduce())
-        self.assertEquals(
-                    self.dsage_server.get_job_result_by_id(jdict['job_id']),
-                    'test')
-
-    def testget_jobs_by_username(self):
-        self.assertEquals(
-                type(self.dsage_server.get_jobs_by_username('yqiang')),
-                list)
-        self.assertEquals(
-                len(self.dsage_server.get_jobs_by_username('test')),
-                0)
-
-        job = expand_job(self.dsage_server.get_job())
-        job.username = 'testing123'
-        job.code = ''
-        jdict = self.dsage_server.submit_job(job.reduce())
-        j = expand_job(self.dsage_server.get_jobs_by_username('testing123')[0])
-        self.assertEquals(j.username, job.username)
-
-    def testsubmit_job(self):
-        jobs = self.create_jobs(10)
-        for job in jobs:
-            jdict = self.dsage_server.submit_job(job.reduce())
-            self.assertEquals(type(jdict), dict)
-            j = expand_job(self.dsage_server.get_job_by_id(jdict['job_id']))
-            self.assert_(isinstance(j, Job))
-
-    def testget_all_jobs(self):
-        jobs = self.dsage_server.get_all_jobs()
-        self.assertEquals(len(jobs), 10)
-
-    def testget_active_jobs(self):
-        jobs = self.dsage_server.get_all_jobs()
-        for job in jobs:
-            job = expand_job(job)
-            job.status = 'processing'
-            jdict = self.dsage_server.submit_job(job.reduce())
-        jobs = self.dsage_server.get_active_jobs()
-        self.assert_(len(jobs) == 10)
-        for job in jobs:
-            job = expand_job(job)
-            self.assert_(isinstance(job, Job))
-            self.assert_(job.status == 'processing')
-            self.assert_(job.update_time < datetime.datetime.now())
-
-    def testget_active_clients_list(self):
-        clients = self.dsage_server.get_client_list()
-        self.assertEquals(len(clients), 0)
-        self.assertEquals(type(clients), list)
-    
-    def testget_killed_jobs_list(self):
-        jobs = self.dsage_server.get_killed_jobs_list()
-        self.assertEquals(len(jobs), 0)
-        
-        jobs = self.dsage_server.get_all_jobs()
-        for job in jobs:
-            job = expand_job(job)
-            job.killed = True
-            self.dsage_server.submit_job(job.reduce())
-
-        jobs = self.dsage_server.get_killed_jobs_list()
-        self.assertEquals(len(jobs), 10)
-        
-        for job in jobs:
-            job = expand_job(job)
-            self.assert_(isinstance(job, Job))
-            self.assertEquals(job.killed, True)
-            self.assert_(job.update_time < datetime.datetime.now())
-
-    def testjob_done(self):
-        job = expand_job(self.dsage_server.get_job())
-        result = 'done'
-        output = 'done '
-        completed = True
-        jdict = self.dsage_server.job_done(job.job_id, output, result, completed)
-        job = expand_job(self.dsage_server.get_job_by_id(jdict['job_id']))
-        self.assertEquals(job.output, output)
-        self.assertEquals(job.result, result)
-        self.assertEquals(job.status, 'completed')
-
-        job = expand_job(self.dsage_server.get_job())
-        result = ['testing', '123']
-        output = 'testing'
-        completed = False
-        jdict = self.dsage_server.job_done(job.job_id, output, result, completed)
-        job = expand_job(self.dsage_server.get_job_by_id(jdict['job_id']))
-        self.assert_(isinstance(job.output, str))
-        self.assert_(job.status != 'completed')
-        
-    def testjob_failed(self):
-        job = expand_job(self.dsage_server.get_job())
-        self.dsage_server.job_failed(job.job_id, 'Failure')
-        job = expand_job(self.dsage_server.get_job_by_id(job.job_id))
-        self.assertEquals(job.failures, 1)
-        self.assertEquals(job.output, 'Failure')
-        self.dsage_server.job_failed(job.job_id, 'Another Failure')
-        job = expand_job(self.dsage_server.get_job_by_id(job.job_id))
-        self.assertEquals(job.failures, 2)
-        self.assertEquals(job.output, 'Another Failure')
-
-    def testkill_job(self):
-        job = expand_job(self.dsage_server.get_job())
-        reason = 'test'
-        id = self.dsage_server.kill_job(job.job_id, reason)
-        job = expand_job(self.dsage_server.get_job_by_id(id))
-        self.assertEquals(job.killed, True)
-
-    def create_jobs(self, n):
-        """This method creates n jobs. """
-
-        jobs = []
-        for i in range(n):
-            jobs.append(Job(name='unittest', username='yqiang', code='2+2'))
-
-        return jobs
-
Index: sage/dsage/server/worker_tracker.py
===================================================================
--- sage/dsage/server/worker_tracker.py	(revision 3866)
+++ sage/dsage/server/worker_tracker.py	(revision 2942)
@@ -17,21 +17,21 @@
 ############################################################################
 
-"""This is a dummy module that keeps a list of connected workers. """
+"""This is a dummy class that keeps a list of connected workers. """
 
 worker_list = []
 
-def add(worker):
-    """
+def add(avatar):
+    r"""
     Adds an avatar to worker_list.
     
     """
     
-    worker_list.append(worker)
+    worker_list.append(avatar)
 
-def remove(worker):
-    """
+def remove(avatar):
+    r"""
     Removes the avatar from the worker_list. 
     
     """
     
-    worker_list.remove(worker)
+    worker_list.remove(avatar)
Index: sage/dsage/tests/data/authorized_keys.db
===================================================================
--- sage/dsage/tests/data/authorized_keys.db	(revision 2885)
+++ sage/dsage/tests/data/authorized_keys.db	(revision 2885)
@@ -0,0 +1,3 @@
+yi:AAAAB3NzaC1yc2EAAAABIwAAAQEAppDp75P57zx6XRCUFUjRh5HrtIKE2Xp6iO39rXALiQmXag+KvvcWL38bk3Vr/X1nAunRAbcudVMkfj05oEZKyhC/XHJ1zoNi/Yj9sqABSZITQeXuU2tftNY7bFQ+WldR3vOdJoItqRdP7yGpCmvd8wpeKex7rJ4+ZpMZCYCil2axdBEltTsoexvFFzDdC4Vrbol4zz+dcgYfEmum4Fm9ovp9QCwR+Ukyru9KA1oHXUZO8MvbLgwpdlvJaV/OffQ11PFFrYPVmFg5APqhpItVf5l1D5Z2rYjTIfvUm9XOHKr+tHFf/M2fSIs/zDseg86wBvKpKpxzFp6Tn8C7FB1CSQ==
+admin:AAAAB3NzaC1yc2EAAAABIwAAAQEAppDp75P57zx6XRCUFUjRh5HrtIKE2Xp6iO39rXALiQmXag+KvvcWL38bk3Vr/X1nAunRAbcudVMkfj05oEZKyhC/XHJ1zoNi/Yj9sqABSZITQeXuU2tftNY7bFQ+WldR3vOdJoItqRdP7yGpCmvd8wpeKex7rJ4+ZpMZCYCil2axdBEltTsoexvFFzDdC4Vrbol4zz+dcgYfEmum4Fm9ovp9QCwR+Ukyru9KA1oHXUZO8MvbLgwpdlvJaV/OffQ11PFFrYPVmFg5APqhpItVf5l1D5Z2rYjTIfvUm9XOHKr+tHFf/M2fSIs/zDseg86wBvKpKpxzFp6Tn8C7FB1CSQ==
+alex:AAAAB3NzaC1yc2EAAAABIwAAAQEAzeF0N+GaxdWvvKVRmRKwzknuygigpZHKSY35LF59aWX8yBF9ZkXWXIiWWaLv+OtmT/I3Vn9564WLFIZKD3AfhCV156uZ5398XSIdJAwQxD9c3S+I/iS9769kJsA0QmALbM3yvHat3x53skPWfdhyOeRuJInnnJwcTFTvX8VtnzMvMnYChfrj+9gJyPVO+5GTNkCeuieStvD5GrBYHI1l/UNAeCjjkcYjndVRXWNXjWlUBI1D3TcEW//6T8YBmH3XkJFly9/C0ZpDavJ9kmzung35utIyG6XHAl1T700a9D9u6oRTNdcdrlwb6YzleAaqBeCn+vrLi7FjspFpz83eZw==
Index: sage/dsage/tests/test_server.py
===================================================================
--- sage/dsage/tests/test_server.py	(revision 2885)
+++ sage/dsage/tests/test_server.py	(revision 2885)
@@ -0,0 +1,31 @@
+############################################################################
+#                                                                     
+#   DSAGE: Distributed SAGE                     
+#                                                                             
+#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
+#                                                                            
+#  Distributed under the terms of the GNU General Public License (GPL)        
+#
+#    This code 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
+#    General Public License for more details.
+#
+#  The full text of the GPL is available at:
+#
+#                  http://www.gnu.org/licenses/
+############################################################################
+
+#import unittest
+#import os
+
+#class ServerTestCase(unittest.TestCase):
+#    def testgetAuthorizedKeys(self):
+#        cur = os.getcwd() 
+#        os.chdir('../dsage/tests/data') 
+#        authorized_keys = getAuthorizedKeys('authorized_keys.db')
+#        for username, key in authorized_keys.iteritems():
+#            self.assert_(isinstance(username, str))
+#            self.assert_(isinstance(key, str))
+#        os.chdir(cur)
+#
Index: age/dsage/tests/testdoc.py
===================================================================
--- sage/dsage/tests/testdoc.py	(revision 3883)
+++ 	(revision )
@@ -1,20 +1,0 @@
-"""nodoctest
-These test that DSage is *really* working for normal users locally
-on their system:
-
-WARNING: Currently these non-blocking startups leave processes
-hanging around!
-
-   sage: dsage.server(blocking=False)
-   sage: dsage.worker(blocking=False)
-   sage: d = DSage()
-   sage: sleep(0.5)
-   sage: a = d('2 + 3')
-   sage: a.wait()
-   sage: a
-   5
-   sage: v = [d('%s^2'%i) for i in range(100,103)]
-   sage: _ = [x.wait() for x in v]
-   sage: print v
-   [10000, 10201, 10404]
-"""
Index: sage/dsage/twisted/misc.py
===================================================================
--- sage/dsage/twisted/misc.py	(revision 3837)
+++ sage/dsage/twisted/misc.py	(revision 2940)
@@ -18,10 +18,10 @@
 
 import threading, sys
+from twisted.internet import defer, reactor
+from twisted.python.failure import Failure
 
 # This code is from 
 # http://twistedmatrix.com/trac/ticket/1042
-def blocking_call_from_thread(func, *args, **kwargs):
-    from twisted.internet import defer, reactor
-    from twisted.python.failure import Failure
+def blockingCallFromThread(func, *args, **kwargs):
     # print func
     # print args
Index: sage/dsage/twisted/pb.py
===================================================================
--- sage/dsage/twisted/pb.py	(revision 3895)
+++ sage/dsage/twisted/pb.py	(revision 3024)
@@ -18,27 +18,20 @@
 
 from twisted.spread import pb
-from twisted.spread import banana
-banana.SIZE_LIMIT = 100*1024*1024 # 100 MegaBytes
-
 from zope.interface import implements
 from twisted.cred import portal, credentials
-from twisted.cred.credentials import ISSHPrivateKey
-from twisted.cred.credentials import Anonymous
 from twisted.spread.interfaces import IJellyable
 from twisted.spread.pb import IPerspective, AsReferenceable
 from twisted.python import log
+from twisted.internet import defer
 
 from sage.dsage.misc.hostinfo import HostInfo
+from sage.dsage.server.server import DSageServer
+import sage.dsage.server.client_tracker as client_tracker
 import sage.dsage.server.worker_tracker as worker_tracker
-from sage.dsage.errors.exceptions import BadTypeError, BadJobError
+from sage.dsage.errors.exceptions import BadTypeError
 
 pb.setUnjellyableForClass(HostInfo, HostInfo)
 
 class WorkerPBServerFactory(pb.PBServerFactory):
-    """
-    This factory serves workers requests.
-    
-    """
-    
     def __init__(self, root):
         pb.PBServerFactory.__init__(self, root)
@@ -62,39 +55,29 @@
                 worker_tracker.remove((broker, host, port))
         
-class PBClientFactory(pb.PBClientFactory):
-    """
-    Custom implementation of the PBClientFactory that supports logging in
-    with public key as well as anonymous credentials.
-    
-    """
-    
-    def login(self, creds, mind=None):
-        if ISSHPrivateKey.providedBy(creds):
-            d = self.getRootObject()
-            d.addCallback(self._cbSendUsername, 
-                          creds.username, 
-                          creds.algName, 
-                          creds.blob, 
-                          creds.sigData,
-                          creds.signature,
-                          mind)
-
-            return d
-        else:
-            d = self.getRootObject()
-            d.addCallback(self._cbAnonymousLogin, mind)
-            return d
+
+
+class ClientPBClientFactory(pb.PBClientFactory):
+    def login(self, creds, client=None):
+        if not isinstance(creds, credentials.SSHPrivateKey):
+            return defer.fail(TypeError())
+
+        d = self.getRootObject()
+        d.addCallback(self._cbSendUsername, 
+                      creds.username, 
+                      creds.algName, 
+                      creds.blob, 
+                      creds.sigData,
+                      creds.signature,
+                      client)
+
+        return d
 
     def _cbSendUsername(self, root, username, alg_name, blob, sig_data,
-                        signature, mind):
+                        signature, client):
+
         d = root.callRemote("login", username, alg_name, blob, sig_data,
-                                signature, mind)
+                                signature, client)
         return d
 
-    def _cbAnonymousLogin(self, root, mind):
-        d = root.callRemote("login_anonymous", mind)
-        
-        return d
-        
 class _SSHKeyPortalRoot(pb._PortalRoot):
     def rootObject(self, broker):
@@ -113,11 +96,5 @@
         
         return d
-    
-    def remote_login_anonymous(self, mind):
-        d = self.portal.login(Anonymous(), mind, IPerspective)
-        d.addCallback(self._loggedIn)
-        
-        return d
-        
+
     def _loggedIn(self, (interface, perspective, logout)):
         if not IJellyable.providedBy(perspective):
@@ -128,242 +105,124 @@
 
 class DefaultPerspective(pb.Avatar):
+    r"""
+    Custom implementation of pb.Avatar so we can keep track of the broker. 
+    
     """
-    Custom implementation of pb.Avatar so we can keep track of the broker. 
+
+    current_connections = 0
+    
+    def perspectiveMessageReceived(self, broker, message, args, kw):
+        self.broker = broker
+
+        return pb.Avatar.perspectiveMessageReceived(self, broker, 
+                                                    message, args, kw)
+
+    def attached(self, avatar, mind):
+        self.current_connections += 1
+        client_tracker.add((avatar, mind))
+
+    def detached(self, avatar, mind):
+        self.current_connections -= 1
+        client_tracker.remove((avatar, mind))
+
+
+class UserPerspective(DefaultPerspective):
+    r"""
+    Defines the perspective of a regular user to the server.
     
     """
-    
+
     def __init__(self, DSageServer, avatarID):
         self.DSageServer = DSageServer
         self.avatarID = avatarID
-        self.connections = 0
         
         log.msg('%s connected' % self.avatarID)
         
-    def perspectiveMessageReceived(self, broker, message, args, kw):
-        self.broker = broker
-
-        return pb.Avatar.perspectiveMessageReceived(self, broker, 
-                                                    message, args, kw)
-
-    def attached(self, avatar, mind):
-        self.connections += 1
-        if isinstance(mind, tuple):
-            self.mind = mind
-            self.host_info = mind[1]
-            self.host_info['ip'] = mind[0].broker.transport.getPeer().host
-            self.host_info['port'] = mind[0].broker.transport.getPeer().port
-            uuid = self.host_info['uuid']
-            if self.DSageServer.monitordb.get_monitor(uuid) is None:
-                self.DSageServer.monitordb.add_monitor(self.host_info)
-            self.DSageServer.monitordb.set_connected(uuid, connected=True)
-        else:
-            self.DSageServer.clientdb.update_login_time(self.avatarID)
-            self.DSageServer.clientdb.set_connected(self.avatarID, connected=True)
-
-    def detached(self, avatar, mind):
-        self.connections -= 1
-        log.msg('%s disconnected' % (self.avatarID))
-        if isinstance(mind, tuple):
-            self.DSageServer.monitordb.set_connected(self.host_info['uuid'], connected=False)
-        else:
-            self.DSageServer.clientdb.set_connected(self.avatarID, connected=False)
-            
-class AnonymousMonitorPerspective(DefaultPerspective):
-    """
-    Defines the perspective of an anonymous worker.
-    
-    """
-    
-    def __init__(self, DSageServer, avatarID):
-        DefaultPerspective.__init__(self, DSageServer, avatarID)
-
-    def attached(self, avatar, mind):
-        self.connections += 1
-        self.mind = mind
-        self.host_info = mind[1]
-        self.host_info['ip'] = mind[0].broker.transport.getPeer().host
-        self.host_info['port'] = mind[0].broker.transport.getPeer().port
-        uuid = self.host_info['uuid']
-        if self.DSageServer.monitordb.get_monitor(uuid) is None:
-            self.DSageServer.monitordb.add_monitor(self.host_info)
-        self.DSageServer.monitordb.set_connected(uuid, connected=True)
-        self.DSageServer.monitordb.set_anonymous(uuid, anonymous=True)
-    
-    def detached(self, avatar, mind):
-        self.connections -= 1
-        log.msg('%s disconnected' % (self.avatarID))
-        self.DSageServer.monitordb.set_connected(self.host_info['uuid'], connected=False)
-            
-    def perspective_get_job(self):
-        """
-        Returns jobs only marked as doable by anonymous workers.
-        
-        """
-        
-        uuid = self.mind[1]['uuid']
-        jdict = self.DSageServer.get_job(anonymous=True)
-        if jdict is not None:
-            self.DSageServer.set_job_uuid(jdict['job_id'], uuid)
-            self.DSageServer.set_busy(uuid, busy=True)
-        else:
-            self.DSageServer.set_busy(uuid, busy=False)
-            
-        return jdict
-        
-    def perspective_get_killed_jobs_list(self):
-        return self.DSageServer.get_killed_jobs_list()
-
-    
-    def perspective_job_failed(self, job_id, traceback):
-        if not isinstance(job_id, str):
-            log.msg('Bad job_id [%s] passed to perspective_job_failed' % (job_id))
-            raise BadTypeError()
-
-        uuid = self.mind[1]['uuid']
-        self.DSageServer.set_busy(uuid, busy=False)
-
-        return self.DSageServer.job_failed(job_id, traceback)
-        
-    def perspective_job_done(self, job_id, output, result, completed):
-        if not (isinstance(job_id, str) or isinstance(completed, bool)):
-            log.msg('Bad job_id passed to perspective_job_done')
-            log.msg('job_id: %s' % (job_id))
-            log.msg('output: %s' % (output))
-            log.msg('completed: %s' % (completed))
-            raise BadTypeError()
-        if completed:
-            uuid = self.mind[1]['uuid']
-            self.DSageServer.set_busy(uuid, busy=False)
-            
-        return self.DSageServer.job_done(job_id, output, result, completed)
-
-    def perspective_submit_host_info(self, hostinfo):
-        if not isinstance(hostinfo, dict):
-            raise BadTypeError()
-        return self.DSageServer.submit_host_info(hostinfo)
-
-class MonitorPerspective(AnonymousMonitorPerspective):
-    """
-    Defines the perspective of an authenticated worker to the server.
-    
-    """
-    def __init__(self, DSageServer, avatarID):
-        DefaultPerspective.__init__(self, DSageServer, avatarID)
-
-    def attached(self, avatar, mind):
-        self.connections += 1
-        self.mind = mind
-        self.host_info = mind[1]
-        self.host_info['ip'] = mind[0].broker.transport.getPeer().host
-        self.host_info['port'] = mind[0].broker.transport.getPeer().port
-        uuid = self.host_info['uuid']
-        if self.DSageServer.monitordb.get_monitor(uuid) is None:
-            self.DSageServer.monitordb.add_monitor(self.host_info)
-        self.DSageServer.monitordb.set_connected(uuid, connected=True)
-        self.DSageServer.monitordb.set_anonymous(uuid, anonymous=False)
-        
-    def perspective_get_job(self):
-        """
-        Returns jobs to authenticated workers.
-        
-        """
-        
-        uuid = self.mind[1]['uuid']
-        jdict = self.DSageServer.get_job(anonymous=False)
-        if jdict is not None:
-            self.DSageServer.set_job_uuid(jdict['job_id'], uuid)
-            self.DSageServer.set_busy(uuid, busy=True)
-        else:
-            self.DSageServer.set_busy(uuid, busy=False)
-            
-        return jdict
-
-class UserPerspective(DefaultPerspective):
-    """
-    Defines the perspective of a regular user to the server.
-    
-    """
-    def __init__(self, DSageServer, avatarID):
-        DefaultPerspective.__init__(self, DSageServer, avatarID)
-        
-    def perspective_get_job_by_id(self, job_id):
-        if not isinstance(job_id, str):
-            log.msg('Bad job_id [%s] passed to get_job_by_id' % (job_id))
-            raise BadTypeError()
-        # log.msg('Returning job %s to %s' % (job_id, self.avatarID))
-        job = self.DSageServer.get_job_by_id(job_id)
+    def perspective_getJob(self):
+        return self.DSageServer.getJob()
+
+    def perspective_getNextJobID(self):
+        job_id = self.DSageServer.getNextJobID()
+        
+        return job_id
+
+    def perspective_getJobByID(self, jobID):
+        if not isinstance(jobID, str):
+            raise BadTypeError()
+            print 'Bad jobID passed to getJobByID'
+        log.msg('Returning job %s to %s' % (jobID, self.avatarID))
+        job = self.DSageServer.getJobByID(jobID)
         
         return job
 
-    def perspective_get_jobs_by_username(self, username, active=True):
-        if not (isinstance(username, str)):
-            log.msg('Bad username [%s] passed to perspective_get_jobs_by_username' % (username))
-            raise BadTypeError()
-
-        jobs = self.DSageServer.get_jobs_by_username(username, active)
+    def perspective_getJobsByAuthor(self, author, job_name, is_active):
+        if not (isinstance(author, str) or 
+                isinstance(is_active, bool) or
+                isinstance(job_name, str)):
+            print 'Bad jobID passed to perspective_getJobsByAuthor'
+            raise BadTypeError()
+
+        jobs = self.DSageServer.getJobsByAuthor(author, job_name, is_active)
 
         return jobs
 
-    def perspective_get_job_result_by_id(self, job_id):
-        if not isinstance(job_id, str):
-            log.msg('Bad job_id [%s] passed to perspective_get_job_result_by_id' % (job_id))
-            raise BadTypeError()
-            
-        return self.DSageServer.get_job_result_by_id(job_id)
-
-    def perspective_get_job_output_by_id(self, job_id):
-        if not isinstance(job_id, str):
-            log.msg('Bad job_id [%s] passed to get_job_output_by_id' % (job_id))
-            raise BadTypeError()
-            
-        return self.DSageServer.get_job_output_by_id(job_id)
-
-    def perspective_sync_job(self, job_id):
-        if not isinstance(job_id, str):
+    def perspective_getJobResultByID(self, jobID):
+        if not isinstance(jobID, str):
+            print 'Bad jobID passed to perspective_getJobResultByID'
+            raise BadTypeError()
+            
+        return self.DSageServer.getJobResultByID(jobID)
+
+    def perspective_getJobOutputByID(self, jobID):
+        if not isinstance(jobID, str):
+            print 'Bad jobID passed to getJobOutputByID'
+            raise BadTypeError()
+            
+        return self.DSageServer.getJobOutputByID(jobID)
+
+    def perspective_syncJob(self, jobID):
+        if not isinstance(jobID, str):
             return None
             
-        return self.DSageServer.sync_job(job_id)
-
-    def perspective_submit_job(self, jdict):
-        if jdict is None:
-            raise BadJobError()
-        if jdict['username'] != self.avatarID:
-            log.msg('username does not match credentials')
-            log.msg('claim: %s' % jdict['username'])
-            log.msg('actual: %s' % self.avatarID)
-            raise BadJobError()
-            
-        return self.DSageServer.submit_job(jdict)
-
-    def perspective_kill_job(self, job_id, reason=None):
-        if not isinstance(job_id, str):
-            log.msg('Bad job_id [%s] passed to perspective_kill_job' % job_id)
-            raise BadTypeError()
-
-        return self.DSageServer.kill_job(job_id, reason)
-
-    def perspective_get_cluster_speed(self):
-        return self.DSageServer.get_cluster_speed()
-        
-    def perspective_get_monitor_list(self):
-        # return [x[1] for x in self.DSageServer.get_worker_list()]
-        return self.DSageServer.get_monitor_list()
-        
-    def perspective_get_client_list(self):
-        return self.DSageServer.get_client_list()
-    
-    def perspective_get_worker_count(self):
-        return self.DSageServer.get_worker_count()
-        
-    def perspective_submit_host_info(self, hostinfo):
-        if not isinstance(hostinfo, dict):
-            raise BadTypeError()
-        return self.DSageServer.submit_host_info(hostinfo)
-
-    def perspective_get_killed_jobs_list(self):
-        return self.DSageServer.get_killed_jobs_list()
-        
+        return self.DSageServer.syncJob(jobID)
+
+    def perspective_submitJob(self, pickled_job):
+        return self.DSageServer.submitJob(pickled_job)
+
+    def perspective_jobDone(self, jobID, output, result, 
+                            completed, worker_info):
+        if not (isinstance(jobID, str) or isinstance(completed, bool)):
+            print 'Bad jobID passed to perspective_jobDone'
+            raise BadTypeError()
+
+        return self.DSageServer.jobDone(jobID, output, result, 
+                                  completed, worker_info)
+
+    def perspective_jobFailed(self, jobID):
+        if not isinstance(jobID, str):
+            print 'Bad jobID passed to perspective_jobFailed'
+            raise BadTypeError()
+
+        return self.DSageServer.jobFailed(jobID)
+
+    def perspective_killJob(self, jobID, reason=None):
+        if not isinstance(jobID, str):
+            print 'Bad jobID passed to perspective_killJob'
+            raise BadTypeError()
+
+        return self.DSageServer.killJob(jobID, reason)
+
+    def perspective_getClusterSpeed(self):
+        return self.DSageServer.getClusterSpeed()
+        
+    def perspective_getWorkerList(self):
+        return [x[1:] for x in self.DSageServer.getWorkerList()]
+            
+    def perspective_getClientList(self):
+        return [avatar[0].avatarID for avatar in
+                self.DSageServer.getClientList()]
+
 class AdminPerspective(UserPerspective):
-    """
+    r"""
     Defines the perspective of the admin. 
     
@@ -372,5 +231,5 @@
     def __init__(self, DSageServer, avatarID):
         UserPerspective.__init__(self, DSageServer, avatarID)
-                
+
 class Realm(object):
     implements(portal.IRealm)
@@ -379,16 +238,13 @@
         self.DSageServer = DSageServer
 
-    def requestAvatar(self, avatarID, mind, *interfaces):        
+    def requestAvatar(self, avatarID, mind, *interfaces):
         if not pb.IPerspective in interfaces:
             raise NotImplementedError, "No supported avatar interface."
         else:
             if avatarID == 'admin':
-                avatar = AdminPerspective(self.DSageServer, avatarID)
-            elif avatarID == 'Anonymous' and mind:
-                avatar = AnonymousMonitorPerspective(self.DSageServer, avatarID)
-            elif mind:
-                avatar = MonitorPerspective(self.DSageServer, avatarID)
+                avatar = AdminPerspective(self.DSageServer)
             else:
                 avatar = UserPerspective(self.DSageServer, avatarID)
         avatar.attached(avatar, mind)
-        return pb.IPerspective, avatar, lambda a=avatar:a.detached(avatar, mind)
+        return pb.IPerspective, avatar, lambda a=avatar:a.detached(avatar, 
+                                                                   mind)
Index: sage/dsage/twisted/pubkeyauth.py
===================================================================
--- sage/dsage/twisted/pubkeyauth.py	(revision 3898)
+++ sage/dsage/twisted/pubkeyauth.py	(revision 2925)
@@ -1,9 +1,9 @@
 ############################################################################
-#
-#   DSAGE: Distributed SAGE
-#
-#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>
-#
-#  Distributed under the terms of the GNU General Public License (GPL)
+#                                                                     
+#   DSAGE: Distributed SAGE                     
+#                                                                             
+#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
+#                                                                            
+#  Distributed under the terms of the GNU General Public License (GPL)        
 #
 #    This code is distributed in the hope that it will be useful,
@@ -22,32 +22,18 @@
 from twisted.conch.ssh import keys
 from twisted.cred import checkers, credentials
-from twisted.cred.credentials import IAnonymous
 from zope.interface import implements
 from twisted.internet import defer
-from twisted.python import log
-from twisted.spread import pb
-
-from sage.dsage.database.clientdb import ClientDatabase
-from sage.dsage.errors.exceptions import AuthenticationError
 
 class PublicKeyCredentialsChecker(object):
-    """
-    This class provides authentication checking using ssh public keys.
-    
-    """
-    
     implements(checkers.ICredentialsChecker)
-    credentialInterfaces = (credentials.ISSHPrivateKey, credentials.IAnonymous)
-    
+    credentialInterfaces = (credentials.ISSHPrivateKey,)
+
     def __init__(self, pubkeydb):
         self.authorizedKeys = self.getAuthorizedKeys(pubkeydb)
-    
+
     def requestAvatarId(self, credentials):
-        if IAnonymous.providedBy(credentials):
-             return 'Anonymous'
-             
         # read the authentication table to make sure we have a fresh copy
         self.authorizedKeys = self.getAuthorizedKeys(self.file_name)
-        
+
         if self.authorizedKeys.has_key(credentials.username):
             userKey = self.authorizedKeys[credentials.username]
@@ -56,5 +42,5 @@
             if not credentials.signature:
                 return defer.fail(error.ValidPublicKey())
-            
+
             pubKey = keys.getPublicKeyObject(data=credentials.blob)
             if keys.verifySignature(pubKey, credentials.signature,
@@ -65,8 +51,8 @@
         else:
             return defer.fail(error.ConchError("Invalid username."))
-    
+
     def getAuthorizedKeys(self, file_name):
         self.file_name = file_name
-        authorized_keys = {}
+        authorized_keys = {} 
         try:
             f = open(file_name)
@@ -78,45 +64,35 @@
         except:
             raise
-        
+
         return authorized_keys
 
 class PublicKeyCredentialsCheckerDB(object):
     implements(checkers.ICredentialsChecker)
-    credentialInterfaces = (credentials.ISSHPrivateKey, credentials.IAnonymous)
-    
-    def __init__(self, clientdb):
-        if not isinstance(clientdb, ClientDatabase):
-            raise TypeError
-        self.clientdb = clientdb
-    
+    credentialInterfaces = (credentials.ISSHPrivateKey,)
+
+    def __init__(self, userdb):
+        self.userdb = userdb
+
+    def getUser(self, username):
+        if not self.userdb.has_key('username'):
+            return False
+        return self.userdb[username]
+
     def requestAvatarId(self, credentials):
-        if IAnonymous.providedBy(credentials):
-            return 'Anonymous'
-        try:
-            user, key = self.get_user(credentials.username)
-        except TypeError:
-            log.msg("Invalid username: '%s'" % credentials.username)
-            return defer.fail(AuthenticationError('Login failed.'))
+        user = self.getUser(credentials.username)
         if user:
-            if not credentials.blob == base64.decodestring(key):
-                log.msg('Invalid key for user %s' % (credentials.username))
-                return defer.fail(AuthenticationError('Login failed.'))
+            userKey = user['public_key']
+            if not credentials.blob == base64.decodestring(userKey):
+                return defer.fail(error.ConchError("Invalid key."))
             if not credentials.signature:
-                log.msg('No signature for user %s ' % (credentials.username))
-                return defer.fail(AuthenticationError('Login failed.'))
-            pub_key = keys.getPublicKeyObject(data=credentials.blob)
-            if keys.verifySignature(pub_key, credentials.signature,
+                return defer.fail(error.ValidPublicKey())
+
+            pubKey = keys.getPublicKeyObject(data=credentials.blob)
+            if keys.verifySignature(pubKey, credentials.signature,
                                     credentials.sigData):
-                # If we get to this stage, it means the user is already
-                # logged in
-                self.clientdb.update_login_time(credentials.username)
                 return credentials.username
             else:
-                log.msg('Invalid signature.')
-                return defer.fail(AuthenticationError('Login failed.'))
+                return defer.fail(error.ConchError("Invalid signature."))
         else:
-            log.msg('Invalid username.')
-            return defer.fail(AuthenticationError('Login failed.'))
-    
-    def get_user(self, username):
-        return self.clientdb.get_user_and_key(username)
+            return defer.fail(error.ConchError("Invalid username."))
+
Index: sage/dsage/twisted/tests/test_pb.py
===================================================================
--- sage/dsage/twisted/tests/test_pb.py	(revision 2964)
+++ sage/dsage/twisted/tests/test_pb.py	(revision 2964)
@@ -0,0 +1,184 @@
+############################################################################
+#                                                                     
+#   DSAGE: Distributed SAGE                     
+#                                                                             
+#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
+#                                                                            
+#  Distributed under the terms of the GNU General Public License (GPL)        
+#
+#    This code 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
+#    General Public License for more details.
+#
+#  The full text of the GPL is available at:
+#
+#                  http://www.gnu.org/licenses/
+############################################################################
+
+import unittest
+import datetime
+import os
+from glob import glob
+from random import randint
+from cPickle import dumps, loads
+import zlib
+
+from sage.dsage.database.job import Job
+from sage.dsage.database.jobdb import JobDatabaseZODB
+from sage.dsage.server.server import DSageServer
+
+class DSageTestCase(unittest.TestCase):
+    def unpickle(self, pickled_job):
+        return loads(zlib.decompress(pickled_job))
+        
+    def setUp(self):
+        self.jobdb = JobDatabaseZODB(test=True)
+        self.dsage_server = DSageServer(self.jobdb, log_level=5)
+        for job in self.createJobs(10):
+            self.dsage_server.jobdb.newJob(job)
+
+    def tearDown(self):
+        self.dsage_server.jobdb._shutdown()
+        files = glob('*.db*')
+        for file in files:
+            os.remove(file)
+
+    def testgetJob(self):
+        pickled_job = self.dsage_server.getJob()
+        self.assertEquals(type(pickled_job), str)
+        job = self.unpickle(pickled_job)
+        self.assert_(isinstance(job, Job))
+
+    def testgetJobByID(self):
+        job = self.createJobs(1)
+        for j in job:
+            jobID = self.jobdb.storeJob(j)
+        self.assert_(isinstance(jobID, str))
+
+    def testgetJobResultsByID(self):
+        job = self.unpickle(self.dsage_server.getJob())
+        job.result = 'test'
+        job.file = ''
+        id = self.dsage_server.submitJob(job.pickle())
+        self.assert_(self.dsage_server.getJobResultByID(id) == 'test')
+
+    def testgetJobsByAuthor(self):
+        self.assert_(isinstance(
+                     self.dsage_server.getJobsByAuthor('Yi Qiang', 
+                                                'unittest',
+                                                True), list))
+
+        self.assert_(len(self.dsage_server.getJobsByAuthor('test', 
+                                                    False,
+                                                    None)) == 0)
+
+        job = self.unpickle(self.dsage_server.getJob())
+        job.author = 'test'
+        job.file = ''
+        id = self.dsage_server.submitJob(job.pickle())
+        self.assert_(self.dsage_server.getJobsByAuthor('test', 
+                                                False,
+                                                None)[0].author == 'test')
+
+    def testsubmitJob(self):
+        jobs = self.createJobs(10)
+        for job in jobs:
+            job.file = ""
+            id = self.dsage_server.submitJob(job.pickle())
+            self.assertEquals(type(id), str)
+            j = self.unpickle(self.dsage_server.getJobByID(id))
+            self.assert_(isinstance(j, Job))
+
+    def testgetJobsList(self):
+        jobs = self.dsage_server.getJobsList()
+        self.assertEquals(len(jobs), 10)
+        for i in xrange(len(jobs)-1):
+            self.assert_(isinstance(jobs[i], Job))
+            self.assert_(jobs[i].num < jobs[i+1].num)
+
+    def testgetActiveJobs(self):
+        jobs = self.dsage_server.getJobsList()
+        for job in jobs:
+            job.status = 'processing'
+            id = self.dsage_server.submitJob(job.pickle())
+        jobs = self.dsage_server.getActiveJobs()
+        self.assert_(len(jobs) == 10)
+        for job in jobs:
+            self.assert_(isinstance(job, Job))
+            self.assert_(job.status == 'processing')
+            self.assert_(job.updated_time < datetime.datetime.now())
+
+    def testgetActiveClientsList(self):
+        pass
+    
+    def testgetKilledJobsList(self):
+        jobs = self.dsage_server.getKilledJobsList()
+        self.assertEquals(len(jobs), 0)
+        
+        jobs = self.dsage_server.getJobsList()
+        for job in jobs:
+            job.killed = True
+            self.dsage_server.submitJob(job.pickle())
+
+        jobs = self.dsage_server.getKilledJobsList()
+        self.assertEquals(len(jobs), 10)
+        
+        for job in jobs:
+            job = self.unpickle(job)
+            self.assert_(isinstance(job, Job))
+            self.assertEquals(job.killed, True)
+            self.assert_(job.updated_time < datetime.datetime.now())
+
+    def testgetNextJobID(self):
+        id = self.dsage_server.getNextJobID()
+        self.assertEquals(type(id), str)
+        self.assert_(id != self.dsage_server.getNextJobID())
+
+    def testjobDone(self):
+        job = self.unpickle(self.dsage_server.getJob())
+        result = 'done'
+        output = 'done '
+        completed = True
+        id = self.dsage_server.jobDone(job.id, output, result, completed,
+                                ('yi@test', 'no info provided'))
+        job = self.unpickle(self.dsage_server.getJobByID(id))
+        self.assertEquals(job.output, output)
+        self.assertEquals(job.result, result)
+        self.assertEquals(job.status, 'completed')
+
+        job = self.unpickle(self.dsage_server.getJob())
+        result = ['testing', '123']
+        output = 'testing'
+        completed = False
+        id = self.dsage_server.jobDone(job.id, output, result, completed, 
+                                ('yi@test', 'no info provided'))
+        job = self.unpickle(self.dsage_server.getJobByID(id))
+        self.assert_(isinstance(job.output, str))
+        self.assert_(job.status != 'completed')
+        
+    def testjobFailed(self):
+        job = self.unpickle(self.dsage_server.getJob())
+        self.dsage_server.jobFailed(job.id)
+        job = self.unpickle(self.dsage_server.getJobByID(job.id))
+        self.assertEquals(job.failures, 1)
+        self.dsage_server.jobFailed(job.id)
+        job = self.unpickle(self.dsage_server.getJobByID(job.id))
+        self.assertEquals(job.failures, 2)
+
+    def testkillJob(self):
+        job = self.unpickle(self.dsage_server.getJob())
+        reason = 'test'
+        id = self.dsage_server.killJob(job.id, reason)
+        job = self.unpickle(self.dsage_server.getJobByID(id))
+        self.assertEquals(job.killed, True)
+
+    def createJobs(self, n):
+        """This method creates n jobs. """
+
+        jobs = []
+        for i in range(n):
+            jobs.append(Job(name='unittest', author='Yi Qiang'))
+
+        return jobs
+
Index: sage/dsage/twisted/tests/test_pubkeyauth.py
===================================================================
--- sage/dsage/twisted/tests/test_pubkeyauth.py	(revision 3905)
+++ sage/dsage/twisted/tests/test_pubkeyauth.py	(revision 2944)
@@ -27,14 +27,12 @@
 from twisted.cred import portal, credentials
 from twisted.conch.ssh import keys
+import twisted.conch
 
 from sage.dsage.twisted.pb import Realm
 from sage.dsage.server.server import DSageServer
 from sage.dsage.twisted.pb import _SSHKeyPortalRoot
-from sage.dsage.twisted.pb import PBClientFactory
-from sage.dsage.twisted.pubkeyauth import PublicKeyCredentialsCheckerDB
-from sage.dsage.database.jobdb import JobDatabaseSQLite
-from sage.dsage.database.monitordb import MonitorDatabase
-from sage.dsage.database.clientdb import ClientDatabase
-from sage.dsage.errors.exceptions import AuthenticationError
+from sage.dsage.twisted.pb import ClientPBClientFactory
+from sage.dsage.twisted.pubkeyauth import PublicKeyCredentialsChecker
+from sage.dsage.database.jobdb import JobDatabaseZODB
 
 DSAGE_DIR = os.path.join(os.getenv('DOT_SAGE'), 'dsage')
@@ -47,4 +45,5 @@
     LOG_FILE = config.get('server_log', 'log_file')
     SSL = config.getint('ssl', 'ssl')
+    WORKER_PORT = config.getint('server', 'worker_port')
     CLIENT_PORT = config.getint('server', 'client_port')
     PUBKEY_DATABASE = os.path.expanduser(config.get('auth',
@@ -68,21 +67,14 @@
 
 class PublicKeyCredentialsCheckerTest(unittest.TestCase):
-    def setUp(self):  
-        self.jobdb = JobDatabaseSQLite(test=True)
-        self.monitordb = MonitorDatabase(test=True)
-        self.clientdb = ClientDatabase(test=True)
-        self.dsage_server = DSageServer(self.jobdb, 
-                                        self.monitordb, 
-                                        self.clientdb,
-                                        log_level=5)
-        self.realm = Realm(self.dsage_server)
-        self.p = _SSHKeyPortalRoot(portal.Portal(Realm(self.dsage_server)))
-        self.clientdb = ClientDatabase(test=True)
-        self.p.portal.registerChecker(
-        PublicKeyCredentialsCheckerDB(self.clientdb))
+    def setUp(self):
+        self.jobdb = JobDatabaseZODB(test=True)
+        self.dsage = DSageServer(self.jobdb, log_level=5)
+        self.realm = Realm(self.dsage)
+        self.p = _SSHKeyPortalRoot(portal.Portal(Realm(self.dsage)))
+        self.p.portal.registerChecker(PublicKeyCredentialsChecker(PUBKEY_DATABASE))
         self.client_factory = pb.PBServerFactory(self.p)
         self.hostname = 'localhost'
-        self.r = reactor.listenTCP(0, self.client_factory)
-        self.port = self.r.getHost().port
+        self.port = CLIENT_PORT
+        self.r = reactor.listenTCP(CLIENT_PORT, self.client_factory)
 
         # public key authentication information
@@ -102,10 +94,5 @@
                                                self.data,
                                                self.signature)
-        c = ConfigParser.ConfigParser()
-        c.read(os.path.join(DSAGE_DIR, 'client.conf'))
-        username = c.get('auth', 'username')
-        pubkey_file = c.get('auth', 'pubkey_file')
-        self.clientdb.add_user(username, pubkey_file)
-        
+
     def tearDown(self):
         self.connection.disconnect()
@@ -117,10 +104,10 @@
 
     def testLogin(self):
-        factory = PBClientFactory()
+        """Tests the login method. """
+        factory = ClientPBClientFactory()
         self.connection = reactor.connectTCP(self.hostname, self.port, factory)
 
         d = factory.login(self.creds, None)
         d.addCallback(self._LoginConnected)
-        
         return d
 
@@ -129,5 +116,5 @@
 
     def testBadLogin(self):
-        factory = PBClientFactory()
+        factory = ClientPBClientFactory()
         self.connection = reactor.connectTCP(self.hostname, self.port, factory)
 
@@ -138,5 +125,5 @@
 
     def testBadLogin2(self):
-        factory = PBClientFactory()
+        factory = ClientPBClientFactory()
         self.connection = reactor.connectTCP(self.hostname, self.port, factory)
         bad_creds = credentials.SSHPrivateKey('this user name should not exit',
@@ -150,8 +137,8 @@
     
     def _BadLoginFailure(self, failure):
-        self.assertEquals(failure.type, str(AuthenticationError))
+        self.assertEquals(failure.type, str(twisted.conch.error.ConchError))
 
     def testBadLogin3(self):
-        factory = PBClientFactory()
+        factory = ClientPBClientFactory()
         self.connection = reactor.connectTCP(self.hostname, self.port, factory)
         bad_creds = credentials.SSHPrivateKey(self.username,
Index: sage/dsage/twisted/tests/test_remote.py
===================================================================
--- sage/dsage/twisted/tests/test_remote.py	(revision 3905)
+++ sage/dsage/twisted/tests/test_remote.py	(revision 2944)
@@ -23,5 +23,4 @@
 import cPickle
 import zlib
-import uuid
 
 from twisted.trial import unittest
@@ -30,17 +29,14 @@
 from twisted.cred import portal, credentials
 from twisted.conch.ssh import keys
-from twisted.python import log
 
 from sage.dsage.twisted.pb import Realm
 from sage.dsage.server.server import DSageServer
 from sage.dsage.twisted.pb import _SSHKeyPortalRoot
-from sage.dsage.twisted.pb import PBClientFactory
-from sage.dsage.twisted.pubkeyauth import PublicKeyCredentialsCheckerDB
-from sage.dsage.database.jobdb import JobDatabaseSQLite
-from sage.dsage.database.monitordb import MonitorDatabase
-from sage.dsage.database.clientdb import ClientDatabase
+from sage.dsage.twisted.pb import ClientPBClientFactory
+from sage.dsage.twisted.pubkeyauth import PublicKeyCredentialsChecker
+from sage.dsage.database.jobdb import JobDatabaseZODB
 from sage.dsage.database.job import Job
 from sage.dsage.errors.exceptions import BadJobError
-from sage.dsage.misc.hostinfo import ClassicHostInfo
+
 
 DSAGE_DIR = os.path.join(os.getenv('DOT_SAGE'), 'dsage')
@@ -53,6 +49,8 @@
     LOG_FILE = config.get('server_log', 'log_file')
     SSL = config.getint('ssl', 'ssl')
+    WORKER_PORT = config.getint('server', 'worker_port')
     CLIENT_PORT = config.getint('server', 'client_port')
-    PUBKEY_DATABASE = os.path.expanduser(config.get('auth', 'pubkey_database'))
+    PUBKEY_DATABASE = os.path.expanduser(config.get('auth',
+                                                    'pubkey_database'))
 
     conf_file = os.path.join(DSAGE_DIR, 'client.conf')
@@ -65,22 +63,7 @@
     PRIVKEY_FILE = os.path.expanduser(config.get('auth', 'privkey_file'))
     PUBKEY_FILE = os.path.expanduser(config.get('auth', 'pubkey_file'))
-    
-    conf_file = os.path.join(DSAGE_DIR, 'worker.conf')
-    config = ConfigParser.ConfigParser()
-    config.read(conf_file)
-    if len(config.get('uuid', 'id')) != 36:
-        config.set('uuid', 'id', str(uuid.uuid1()))
-        f = open(conf_file, 'w')
-        config.write(f)
-    UUID = config.get('uuid', 'id')
-    WORKERS = config.getint('general', 'workers')
-    
-except Exception, msg:
-    log.msg(msg)
+except:
     raise 
 # End reading configuration
-hf = ClassicHostInfo().host_info
-hf['uuid'] = UUID
-hf['workers'] = WORKERS
 
 Data =  ''.join([chr(i) for i in [random.randint(65, 123) for n in
@@ -88,29 +71,18 @@
 
 class ClientRemoteCallsTest(unittest.TestCase):
-    """
-    Tests of remote procedure calls go here.
-    
-    """
-    
     def unpickle(self, pickled_job):
         return cPickle.loads(zlib.decompress(pickled_job))
     
     def setUp(self):
-        self.jobdb = JobDatabaseSQLite(test=True)
-        self.monitordb = MonitorDatabase(test=True)
-        self.clientdb = ClientDatabase(test=True)
-        self.dsage_server = DSageServer(self.jobdb, 
-                                        self.monitordb, 
-                                        self.clientdb,
-                                        log_level=5)
-        self.realm = Realm(self.dsage_server)
-        self.p = _SSHKeyPortalRoot(portal.Portal(self.realm))
-        self.clientdb = ClientDatabase(test=True)
-        self.p.portal.registerChecker(PublicKeyCredentialsCheckerDB(self.clientdb))
+        self.jobdb = JobDatabaseZODB(test=True)
+        self.dsage = DSageServer(self.jobdb, log_level=5)
+        self.realm = Realm(self.dsage)
+        self.p = _SSHKeyPortalRoot(portal.Portal(Realm(self.dsage)))
+        self.p.portal.registerChecker(PublicKeyCredentialsChecker(PUBKEY_DATABASE))
         self.client_factory = pb.PBServerFactory(self.p)
         self.hostname = 'localhost'
-        self.server = reactor.listenTCP(0, self.client_factory)
-        self.port = self.server.getHost().port
-        
+        self.port = CLIENT_PORT
+        self.r = reactor.listenTCP(CLIENT_PORT, self.client_factory)
+
         # public key authentication information
         self.username = USERNAME
@@ -129,10 +101,5 @@
                                                self.data,
                                                self.signature)
-        c = ConfigParser.ConfigParser()
-        c.read(os.path.join(DSAGE_DIR, 'client.conf'))
-        username = c.get('auth', 'username')
-        pubkey_file = c.get('auth', 'pubkey_file')
-        self.clientdb.add_user(username, pubkey_file)
-        
+
     def tearDown(self):
         self.connection.disconnect()
@@ -141,17 +108,55 @@
         for file in files:
             os.remove(file)
-        return self.server.stopListening()
-
-    def _catch_failure(self, failure, *args):
-        log.msg("Error: ", failure.getErrorMessage())
-        log.msg("Traceback: ", failure.printTraceback())
-        
+        return self.r.stopListening()
+
+    def testremoteGetJobEmptyQueue(self):
+        """Tests perspective_getJob on an empty database"""
+        factory = ClientPBClientFactory()
+        self.connection = reactor.connectTCP(self.hostname, self.port,
+                                             factory)
+
+        d = factory.login(self.creds, None)
+        d.addCallback(self._LoginConnected)
+        return d
+
+    def _LoginConnected(self, remoteobj):
+        d = remoteobj.callRemote('getJob')
+        d.addCallback(self._gotNoJob)
+        return d
+
+    def _gotNoJob(self, job):
+        self.assertEquals(job, None)
+
+    def testremoteGetJob(self):
+        """Tests perspective_getJob"""
+        jobs = self.createJobs(10)
+        for job in jobs:
+            self.jobdb.newJob(job)
+
+        factory = ClientPBClientFactory()
+        self.connection = reactor.connectTCP(self.hostname, self.port, 
+                                             factory)
+
+        d = factory.login(self.creds, None)
+        d.addCallback(self._LoginConnected1)
+        return d
+
+    def _LoginConnected1(self, remoteobj):
+        d = remoteobj.callRemote('getJob')
+        d.addCallback(self._gotJob)
+        return d
+
+    def _gotJob(self, job):
+        self.assert_(isinstance(job, str))
+        import cPickle, zlib
+        job = self.unpickle(job)
+        self.assert_(isinstance(job, Job))
+
     def testremoteSubmitJob(self):
-        """tests perspective_submit_job"""
-        jobs = self.create_jobs(1)
-
-        factory = PBClientFactory()
-        self.connection = reactor.connectTCP(self.hostname, 
-                                             self.port, 
+        """tests perspective_submitJob"""
+        jobs = self.createJobs(1)
+
+        factory = ClientPBClientFactory()
+        self.connection = reactor.connectTCP(self.hostname, self.port, 
                                              factory)
 
@@ -162,19 +167,17 @@
     def _LoginConnected2(self, remoteobj, jobs):
         job = jobs[0]
-        job.code = "2+2"
-        d = remoteobj.callRemote('submit_job', job.reduce())
-        d.addCallback(self._got_jdict)
-        return d
-
-    def _got_jdict(self, jdict):
-        self.assertEquals(type(jdict), dict)
-        self.assertEquals(type(jdict['job_id']), str)
+        job.file = ""
+        d = remoteobj.callRemote('submitJob', job.pickle())
+        d.addCallback(self._gotJobID)
+        return d
+
+    def _gotJobID(self, jobID):
+        self.assertEquals(type(jobID), str)
 
     def testremoteSubmitBadJob(self):
-        """tests perspective_submit_job"""
-
-        factory = PBClientFactory()
-        self.connection = reactor.connectTCP(self.hostname, 
-                                             self.port, 
+        """tests perspective_submitJob"""
+
+        factory = ClientPBClientFactory()
+        self.connection = reactor.connectTCP(self.hostname, self.port, 
                                              factory)
 
@@ -184,5 +187,5 @@
 
     def _LoginConnected3(self, remoteobj):
-        d = remoteobj.callRemote('submit_job', None)
+        d = remoteobj.callRemote('submitJob', None)
         d.addErrback(self._gotNoJobID)
         return d
@@ -191,171 +194,13 @@
         self.assertEquals(BadJobError, failure.check(BadJobError))
 
-    def create_jobs(self, n):
+    def createJobs(self, n):
         """This method creates n jobs. """
 
         jobs = []
         for i in range(n):
-            jobs.append(Job(name='unittest', username=self.username))
+            jobs.append(Job(name='unittest', author='Yi Qiang'))
 
         return jobs
 
-class MonitorRemoteCallsTest(unittest.TestCase):
-    """
-    Tests remote calls for monitors.
-    
-    """
-    
-    def setUp(self):
-        self.jobdb = JobDatabaseSQLite(test=True)
-        self.monitordb = MonitorDatabase(test=True)
-        self.clientdb = ClientDatabase(test=True)
-        self.dsage_server = DSageServer(self.jobdb, 
-                                        self.monitordb,
-                                        self.clientdb,
-                                        log_level=5)
-        self.realm = Realm(self.dsage_server)
-        self.p = _SSHKeyPortalRoot(portal.Portal(self.realm))
-        self.p.portal.registerChecker(
-        PublicKeyCredentialsCheckerDB(self.clientdb))
-        self.client_factory = pb.PBServerFactory(self.p)
-        self.hostname = 'localhost'
-        self.server = reactor.listenTCP(0, self.client_factory)
-        self.port = self.server.getHost().port
-        # public key authentication information
-        self.username = USERNAME
-        self.pubkey_file = PUBKEY_FILE
-        self.privkey_file = PRIVKEY_FILE
-        self.public_key_string = keys.getPublicKeyString(
-                                 filename=self.pubkey_file)
-        self.private_key = keys.getPrivateKeyObject(filename=self.privkey_file)
-        self.public_key = keys.getPublicKeyObject(self.public_key_string)
-        self.alg_name = 'rsa'
-        self.blob = keys.makePublicKeyBlob(self.public_key)
-        self.data = Data
-        self.signature = keys.signData(self.private_key, self.data)
-        self.creds = credentials.SSHPrivateKey(self.username,
-                                               self.alg_name,
-                                               self.blob, 
-                                               self.data,
-                                               self.signature)
-        c = ConfigParser.ConfigParser()
-        c.read(os.path.join(DSAGE_DIR, 'client.conf'))
-        username = c.get('auth', 'username')
-        pubkey_file = c.get('auth', 'pubkey_file')
-        self.clientdb.add_user(username, pubkey_file)  
-        
-    def tearDown(self):
-        self.connection.disconnect()
-        self.jobdb._shutdown()
-        files = glob('*.db*')
-        for file in files:
-            os.remove(file)
-        return self.server.stopListening() 
-    
-    def testremote_get_job(self):
-        job = Job()
-        job.code = "2+2"
-        self.dsage_server.submit_job(job.reduce())
-        factory = PBClientFactory()
-        self.connection = reactor.connectTCP(self.hostname, 
-                                             self.port, 
-                                             factory)                                        
-        d = factory.login(self.creds, (pb.Referenceable(), hf))
-        d.addCallback(self._logged_in)
-        d.addCallback(self._get_job)
-        
-        return d
-    
-    def _logged_in(self, remoteobj):
-        self.assert_(remoteobj is not None)
-        
-        return remoteobj
-        
-    def _get_job(self, remoteobj):
-        d = remoteobj.callRemote('get_job')
-        d.addCallback(self._got_job)
-        
-        return d
-        
-    def _got_job(self, jdict):
-        self.assertEquals(type(jdict), dict)
-    
-    def testremote_job_done(self):
-        factory = PBClientFactory()
-        self.connection = reactor.connectTCP(self.hostname, self.port, factory)                                       
-        d = factory.login(self.creds, (pb.Referenceable(), hf))
-        job = Job()
-        job.code = "2+2"
-        jdict = self.dsage_server.submit_job(job.reduce())
-        d.addCallback(self._logged_in)
-        d.addCallback(self._job_done, jdict)
-        
-        return d
-    
-    def _job_done(self, remoteobj, jdict):
-        job_id = jdict['job_id']
-        result = jdict['result']
-        d = remoteobj.callRemote('job_done', job_id, 'Nothing.', result, False)
-        d.addCallback(self._done_job)
-        
-        return d
-    
-    def _done_job(self, jdict):
-        self.assertEquals(type(jdict), dict)
-        self.assertEquals(jdict['status'], 'new')
-        self.assertEquals(jdict['output'], 'Nothing.')
-    
-    def testremote_job_failed(self):
-        factory = PBClientFactory()
-        self.connection = reactor.connectTCP(self.hostname, 
-                                             self.port, 
-                                             factory)
-        job = Job()
-        job.code = "2+2"
-        jdict = self.dsage_server.submit_job(job.reduce())
-        d = factory.login(self.creds, (pb.Referenceable(), hf))
-        d.addCallback(self._logged_in)
-        d.addCallback(self._job_failed, jdict)
-        
-        return d
-        
-    def _job_failed(self, remoteobj, jdict):
-        d = remoteobj.callRemote('job_failed', jdict['job_id'], 'Failure')
-        d.addCallback(self._failed_job)
-        
-        return d
-        
-    def _failed_job(self, jdict):
-        self.assertEquals(type(jdict), dict) 
-        self.assertEquals(jdict['failures'], 1)
-        self.assertEquals(jdict['output'], 'Failure')
-        
-    def testget_killed_jobs_list(self):
-        factory = PBClientFactory()
-        self.connection = reactor.connectTCP(self.hostname, 
-                                             self.port, 
-                                             factory)
- 
-        job = Job()
-        job.code = "2+2"
-        job.killed = True
-        jdict = self.dsage_server.submit_job(job.reduce())
-        d = factory.login(self.creds, (pb.Referenceable(), hf))
-        d.addCallback(self._logged_in)
-        d.addCallback(self._get_killed_jobs_list)
-        d.addCallback(self._got_killed_jobs_list, jdict)
-        
-        return d
-    
-    def _get_killed_jobs_list(self, remoteobj):
-        d = remoteobj.callRemote('get_killed_jobs_list')
-        
-        return d
-    
-    def _got_killed_jobs_list(self, killed_jobs_list, jdict):
-        self.assertEquals(len(killed_jobs_list), 1)
-        self.assertEquals(killed_jobs_list[0]['job_id'], jdict['job_id'])
-        
-        
 if __name__ == 'main':
     unittest.main()
Index: sage/dsage/twisted/tests/test_server.py
===================================================================
--- sage/dsage/twisted/tests/test_server.py	(revision 2925)
+++ sage/dsage/twisted/tests/test_server.py	(revision 2925)
@@ -0,0 +1,31 @@
+############################################################################
+#                                                                     
+#   DSAGE: Distributed SAGE                     
+#                                                                             
+#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
+#                                                                            
+#  Distributed under the terms of the GNU General Public License (GPL)        
+#
+#    This code 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
+#    General Public License for more details.
+#
+#  The full text of the GPL is available at:
+#
+#                  http://www.gnu.org/licenses/
+############################################################################
+
+#import unittest
+#import os
+
+#class ServerTestCase(unittest.TestCase):
+#    def testgetAuthorizedKeys(self):
+#        cur = os.getcwd() 
+#        os.chdir('../dsage/tests/data') 
+#        authorized_keys = getAuthorizedKeys('authorized_keys.db')
+#        for username, key in authorized_keys.iteritems():
+#            self.assert_(isinstance(username, str))
+#            self.assert_(isinstance(key, str))
+#        os.chdir(cur)
+#
Index: sage/ext/cdefs.pxi
===================================================================
--- sage/ext/cdefs.pxi	(revision 3922)
+++ sage/ext/cdefs.pxi	(revision 3292)
@@ -113,14 +113,4 @@
     void mpz_xor (mpz_t rop, mpz_t op1, mpz_t op2)
     int mpz_root (mpz_t rop, mpz_t op, unsigned long int n)
-    
-    int mpz_odd_p (mpz_t op)
-    int mpz_even_p (mpz_t op)
-    
-    int mpz_perfect_power_p (mpz_t op)
-    int mpz_perfect_square_p (mpz_t op)
-    
-    int mpz_jacobi (mpz_t a, mpz_t b)
-    int mpz_kronecker (mpz_t a, mpz_t b)
-    int mpz_kronecker_si (mpz_t a, long b)
 
     # The mpq type
Index: sage/ext/interactive_constructors_c.pyx
===================================================================
--- sage/ext/interactive_constructors_c.pyx	(revision 3973)
+++ sage/ext/interactive_constructors_c.pyx	(revision 1854)
@@ -34,11 +34,13 @@
         sage: GF(9,'c')
         Finite Field in c of size 3^2
-        sage: c^3
-		c^3
+        sage: c
+        Traceback (most recent call last):
+        ...
+        NameError: name 'c' is not defined
         sage: inject_on(verbose=False)
         sage: GF(9,'c')
         Finite Field in c of size 3^2
-        sage: c^3
-		2*c + 1
+        sage: c
+        c    
 
     ROLL YOUR OWN: If a constructor you would like to auto inject
Index: sage/functions/all.py
===================================================================
--- sage/functions/all.py	(revision 4050)
+++ sage/functions/all.py	(revision 2106)
@@ -1,6 +1,4 @@
 
 from piecewise import Piecewise
-
-piecewise = Piecewise
 
 from transcendental import (exponential_integral_1,
@@ -8,4 +6,5 @@
                             zeta, zeta_symmetric)
 
+# This is too terrible code.
 #from elementary import (cosine, sine, exponential,
 #                        ElementaryFunction,
@@ -13,9 +12,10 @@
 
 from special    import (bessel_I, bessel_J, bessel_K, bessel_Y,
-                        hypergeometric_U,
+                        hypergeometric_U, incomplete_gamma,
                         spherical_bessel_J, spherical_bessel_Y,
                         spherical_hankel1, spherical_hankel2,
                         spherical_harmonic, jacobi,
-                        inverse_jacobi, dilog,
+                        inverse_jacobi, sinh, cosh,
+                        tanh, coth, sech, csch, dilog,
                         lngamma, exp_int, error_fcn)
                         
@@ -36,4 +36,4 @@
 
 from constants import (pi, e, NaN, golden_ratio, log2, euler_gamma, catalan,
-                       khinchin, twinprime, merten, brun, I)
+                       khinchin, twinprime, merten, brun)
 
Index: sage/functions/constants.py
===================================================================
--- sage/functions/constants.py	(revision 4065)
+++ sage/functions/constants.py	(revision 3290)
@@ -19,5 +19,5 @@
     euler_gamma
     sage: catalan       # the Catalon constant
-    catalan
+    K
     sage: khinchin      # Khinchin's constant
     khinchin
@@ -54,13 +54,13 @@
 can be coerced into other systems or evaluated.
     sage: a = pi + e*4/5; a
-    pi + 4*e/5
+    (pi + ((e*4)/5))
     sage: maxima(a)
-    %pi+4*%e/5
-    sage: RealField(15)(a)           # 15 *bits* of precision
-    5.316
-    sage: gp(a)             
-    5.316218116357029426750873360              # 32-bit
-    5.3162181163570294267508733603616328824    # 64-bit
-    sage: print mathematica(a)                     # optional
+    %pi + 4*%e/5
+    sage: a.str(15)      # 15 *bits* of precision
+    '5.316'
+    sage: gp(a)
+    5.316218116357029426750873360            # 32-bit
+    5.3162181163570294267508733603616328824  # 64-bit
+    sage: mathematica(a)                     # optional
      4 E
      --- + Pi
@@ -102,16 +102,12 @@
 
 EXAMPLES: Arithmetic with constants
-    sage: f = I*(e+1); f
-    (e + 1)*I
-    sage: f^2
-    -(e + 1)^2
 
     sage: pp = pi+pi; pp
-    2*pi
+    (pi + pi)
     sage: R(pp)
     6.2831853071795864769252867665590057683943387987502116419499
     
-    sage: s = (1 + e^pi); s
-    e^pi + 1
+    sage: s = (1 + e^pi);s
+    (1 + (e^pi))
     sage: R(s)
     24.140692632779269005729086367948547380266106242600211993445
@@ -119,6 +115,6 @@
     23.140692632779269005729086367948547380266106242600211993445
 
-    sage: l = (1-log2)/(1+log2); l
-    (1 - log(2))/(log(2) + 1)
+    sage: l = (1-log2)/(1+log2);l
+    ((1 - log2)/(1 + log2))
     sage: R(l)
     0.18123221829928249948761381864650311423330609774776013488056
@@ -160,31 +156,30 @@
 from functions import Function_gen, Function_arith, Function, FunctionRing_class
 
-
 ######################
 # Ring of Constants
 ######################
 
-## class ConstantRing_class(FunctionRing_class):
-##     def _repr_(self):
-##         return "Ring of Real Mathematical Constants"
-
-##     def __cmp__(self, right):
-##         if isinstance(right, ConstantRing_class):
-##             return 0
-##         return -1
+class ConstantRing_class(FunctionRing_class):
+    def _repr_(self):
+        return "Ring of Real Mathematical Constants"
+
+    def __cmp__(self, right):
+        if isinstance(right, ConstantRing_class):
+            return 0
+        return -1
         
-##     def __call__(self, x):
-##         try:
-##             return self._coerce_(x)
-##         except TypeError:
-##             return Constant_gen(x)
-
-##     def _coerce_impl(self, x):
-##         if isinstance(x, (sage.rings.integer.Integer,
-##                           sage.rings.rational.Rational, int, long)):
-##             return Constant_gen(x)
-##         raise TypeError, 'no canonical coercion of element into self.'
-
-## ConstantRing = ConstantRing_class()
+    def __call__(self, x):
+        try:
+            return self._coerce_(x)
+        except TypeError:
+            return Constant_gen(x)
+
+    def _coerce_impl(self, x):
+        if isinstance(x, (sage.rings.integer.Integer,
+                          sage.rings.rational.Rational, int, long)):
+            return Constant_gen(x)
+        raise TypeError, 'no canonical coercion of element into self.'
+
+ConstantRing = ConstantRing_class()
 
 
@@ -192,35 +187,9 @@
 # Constant functions
 ######################
-import sage.calculus.calculus
 
 class Constant(Function):
     def __init__(self, conversions={}):
         self._conversions = conversions
-        RingElement.__init__(self, sage.calculus.calculus.SR)
-
-    def _has_op(self, x):
-        return False
-
-    def substitute(self, *args, **kwds):
-        return self
-
-    def _recursive_sub(self, kwds):
-        return self
-
-    def _recursive_sub(self, kwds):
-        return self
-
-    def _recursive_sub_over_ring(self, kwds, ring):
-        return ring(self)
-
-    def variables(self):
-        return []
-
-    def _ser(self):
-        try:
-            return self.__ser
-        except AttributeError:
-            self.__ser = sage.calculus.calculus.SR._coerce_impl(self)
-            return self.__ser
+        RingElement.__init__(self, ConstantRing)
 
     def _neg_(self):
@@ -233,31 +202,23 @@
         return Integer(int(float(self)))
 
-    def _latex_(self):
-        return '\\text{%s}'%self
-    
-    def _complex_mpfr_field_(self, R):
-        return R(self._mpfr_(R._real_field()))
-
-    def _real_double_(self, R):
-        return R(float(self))
-
-    def _complex_double_(self, R):
-        return R(float(self))
-    
     # The following adds formal arithmetic support for generic constant
     def _add_(self, right):
-        return self._ser() + right
+        return Constant_arith(self, right, operator.add)
 
     def _sub_(self, right):
-        return self._ser() - right
+        return Constant_arith(self, right, operator.sub)
 
     def _mul_(self, right):
-        return self._ser() * right
+        return Constant_arith(self, right, operator.mul)
 
     def _div_(self, right):
-        return self._ser() / right
+        return Constant_arith(self, right, operator.div)
 
     def __pow__(self, right):
-        return self._ser() ** right
+        try:
+            right = self.parent()._coerce_(right)
+        except TypeError:
+            raise TypeError, "computation of %s^%s not defined"%(self, right)
+        return Constant_arith(self, right, operator.pow)
 
     def _interface_is_cached_(self):
@@ -299,5 +260,6 @@
         Function_arith.__init__(self, x, y, op)
         Constant.__init__(self)
-       
+        
+
 class Pi(Constant):
     """
@@ -319,5 +281,5 @@
         3.1415926535897932384626433832795028841971693993751058209749
         sage: pp = pi+pi; pp
-        2*pi
+        (pi + pi)
         sage: R(pp)
         6.2831853071795864769252867665590057683943387987502116419499
@@ -333,5 +295,5 @@
              'matlab':'pi','maple':'Pi','octave':'pi','pari':'Pi'})
         
-    def _repr_(self, simplify=True):
+    def _repr_(self):
         return "pi"
 
@@ -348,6 +310,6 @@
         return R.pi()
 
-    def _real_double_(self,R):
-        return R.pi()
+    def _real_double_(self):
+        return sage.rings.all.RD.pi()
 
     def __abs__(self):
@@ -367,72 +329,4 @@
 pi = Pi()
 
-
-class I_class(Constant):
-    """
-    The formal square root of -1.
-    
-    EXAMPLES:
-        sage: I
-        I
-        sage: I^2
-        -1
-        sage: float(I)
-        Traceback (most recent call last):
-        ...
-        TypeError
-        sage: gp(I)
-        I
-        sage: RR(I)
-        Traceback (most recent call last):
-        ...
-        TypeError
-        sage: C = ComplexField(200); C
-        Complex Field with 200 bits of precision
-        sage: C(I)
-        1.0000000000000000000000000000000000000000000000000000000000*I
-        sage: z = I + I; z
-        2*I
-        sage: C(z)
-        2.0000000000000000000000000000000000000000000000000000000000*I
-        sage: maxima(2*I)
-        2*%i
-    """
-    def __init__(self):
-        Constant.__init__(self,
-            {'axiom':'%i', 
-             'maxima':'%i','gp':'I','mathematica':'I',
-             'matlab':'i','maple':'I','octave':'i','pari':'I'})
-        
-    def _repr_(self, simplify=True):
-        return "I"
-
-    def _latex_(self):
-        return "i"
-
-    def _mathml_(self):
-        return "<mi>&i;</mi>"
-
-    def __float__(self):
-        raise TypeError
-
-    def _mpfr_(self, R):
-        raise TypeError
-
-    def _complex_mpfr_field_(self, R):
-        return R.gen()
-
-    def _complex_double_(self, C):
-        return C.gen()
-
-    def _real_double_(self, R):
-        raise TypeError        
-
-    def __abs__(self):
-        return Integer(1)
-
-    def floor(self):
-        raise TypeError
-
-I = I_class()
 
 class E(Constant):
@@ -448,5 +342,5 @@
         2.7182818284590452353602874713526624977572470936999595749670
         sage: em = 1 + e^(1-e); em
-        e^(1 - e) + 1
+        (1 + (e^(1 - e)))
         sage: R(em)
         1.1793740787340171819619895873183164984596816017589156131574
@@ -470,5 +364,5 @@
              'octave':'e'}) 
     
-    def _repr_(self, simplify=True):
+    def _repr_(self):
         return 'e'
 
@@ -485,6 +379,6 @@
         return Integer(2)
 
-    def _real_double_(self, R):
-        return R(1).exp()
+    def _real_double_(self):
+        return sage.rings.all.RD.e()
 
     # This just gives a string in singular anyways, and it's
@@ -497,4 +391,6 @@
 ee = e
 
+
+
 class NotANumber(Constant): 
     """
@@ -505,5 +401,5 @@
 	    {'matlab':'NaN'})
     
-    def _repr_(self, simplify=True):
+    def _repr_(self):
         return 'NaN'
  
@@ -511,6 +407,6 @@
         return R('NaN') #??? nan in mpfr: void mpfr_set_nan (mpfr_t x)
 
-    def _real_double_(self, R):
-        return R.nan()
+    def _real_double_(self):
+        return sage.rings.all.RD.nan()
 
 NaN = NotANumber()
@@ -528,7 +424,7 @@
         1.6180339887498948482045868343656381177203091798057628621354
         sage: grm = maxima(golden_ratio);grm
-        (sqrt(5)+1)/2
+        (sqrt(5) + 1)/2
         sage: grm + grm
-        sqrt(5)+1
+        sqrt(5) + 1
         sage: float(grm + grm)
         3.2360679774997898
@@ -539,5 +435,5 @@
 				'pari':'(1+sqrt(5))/2','octave':'(1+sqrt(5))/2',
 				'kash':'(1+Sqrt(5))/2'})
-    def _repr_(self, simplify=True):
+    def _repr_(self):
         return 'golden_ratio'
 
@@ -548,5 +444,5 @@
         return float(0.5)*(float(1.0)+math.sqrt(float(5.0)))
 
-    def _real_double_(self, R):
+    def _real_double_(self):
         """
         EXAMPLES:
@@ -554,5 +450,5 @@
             1.61803398875
         """
-        return R('1.61803398874989484820458')
+        return sage.rings.all.RDF(1.61803398874989484820458)
 
     def _mpfr_(self,R):  #is this OK for _mpfr_ ?
@@ -576,6 +472,6 @@
         sage: R(log2)
         0.69314718055994530941723212145817656807550013436025525412068
-        sage: l = (1-log2)/(1+log2); l
-        (1 - log(2))/(log(2) + 1)
+        sage: l = (1-log2)/(1+log2);l
+        ((1 - log2)/(1 + log2))
         sage: R(l)
         0.18123221829928249948761381864650311423330609774776013488056
@@ -596,5 +492,5 @@
 				'pari':'log(2)','octave':'log(2)'})
 
-    def _repr_(self, simplify=True):
+    def _repr_(self):
         return 'log2'
 
@@ -605,5 +501,5 @@
         return math.log(2) 
 
-    def _real_double_(self, R):
+    def _real_double_(self):
         """
         EXAMPLES:
@@ -611,5 +507,5 @@
             0.69314718056
         """
-        return R.log2()
+        return sage.rings.all.RD.log2()
 
     def _mpfr_(self,R):
@@ -633,6 +529,6 @@
         sage: R(euler_gamma)
         0.57721566490153286060651209008240243104215933593992359880577
-        sage: eg = euler_gamma + euler_gamma; eg
-        2*euler_gamma
+        sage: eg = euler_gamma + euler_gamma;eg
+        (euler_gamma + euler_gamma)
         sage: R(eg)
         1.1544313298030657212130241801648048620843186718798471976115
@@ -641,8 +537,7 @@
         Constant.__init__(self,
 	    {'kash':'EulerGamma(R)','maple':'gamma', 
-             'mathematica':'EulerGamma','pari':'Euler',
-             'maxima':'%gamma', 'maxima':'euler_gamma'})    
-
-    def _repr_(self, simplify=True):
+             'mathematica':'EulerGamma','pari':'Euler'})    
+
+    def _repr_(self):
         return 'euler_gamma'
 
@@ -653,5 +548,5 @@
         return R.euler_constant()
 
-    def _real_double_(self, R):
+    def _real_double_(self):
         """
         EXAMPLES:
@@ -659,5 +554,5 @@
             0.577215664902
         """
-        return R.euler_constant()
+        return sage.rings.all.RD.euler()
 
     def floor(self):
@@ -672,19 +567,20 @@
 
     EXAMPLES:
-        sage: catalan^2 + merten
-        merten + catalan^2
     """
     def __init__(self):
         Constant.__init__(self,
              {'mathematica':'Catalan','kash':'Catalan(R)', #kash: R is default prec
-              'maple':'Catalan', 'maxima':'catalan'}) 
+	      'maple':'Catalan'}) 
                                          
-    def _repr_(self, simplify=True):
-        return 'catalan'
+    def _repr_(self):
+        return 'K'
+
+    def _latex_(self):
+        return 'K'
 
     def _mpfr_(self, R):  
         return R.catalan_constant() 
 
-    def _real_double_(self, R):
+    def _real_double_(self):
         """
         EXAMPLES:
@@ -693,5 +589,5 @@
             0.915965594177
         """
-        return R('0.91596559417721901505460351493252')
+        return sage.rings.all.RDF(0.91596559417721901505460351493252)
 
     def __float__(self):
@@ -721,10 +617,14 @@
         Khinchin
         sage: m.N(200)                                 # optional
-             2.6854520010653064453097148354817956938203822939944629530511523455572188595371520028011411749318476979951534659052880900828976777164109630517925334832596683818523154213321194996260393285220448194096180686641664289    # 32-bit
-             2.6854520010653064453097148354817956938203822939944629530511523455572188595371520028011411749318476979951534659052880900828976777164109630517925334832596683818523154213321194996260393285220448194096181                # 64-bit
+             2.685452001065306445309714835481795693820382293994462953051152345557     # 32-bit
+        >    218859537152002801141174931847697995153465905288090082897677716410963051 # 32-bit
+        >    7925334832596683818523154213321194996260393285220448194096181            # 32-bit
+             2.685452001065306445309714835481795693820382293994462953051152345557     # 64-bit
+        >    218859537152002801141174931847697995153465905288090082897677716410963051 # 64-bit
+        >    7925334832596683818523154213321194996260393285220448194096181            # 64-bit
     """
     def __init__(self):
         Constant.__init__(self,
-             {'maxima':'khinchin', 'mathematica':'Khinchin'}) #Khinchin is only implemented in Mathematica
+             {'mathematica':'Khinchin'}) #Khinchin is only implemented in Mathematica
         
         # digits come from http://pi.lacim.uqam.ca/piDATA/khintchine.txt
@@ -732,5 +632,5 @@
         self.__bits = len(self.__value)*3-1   # underestimate
 
-    def _repr_(self, simplify=True):
+    def _repr_(self):
         return 'khinchin'
 
@@ -740,5 +640,5 @@
         raise NotImplementedError, "Khinchin's constant only available up to %s bits"%self.__bits
 
-    def _real_double_(self, R):
+    def _real_double_(self):
         """
         EXAMPLES:
@@ -746,5 +646,5 @@
             2.68545200107
         """
-	return R('2.685452001065306445309714835481795693820')
+	return sage.rings.all.RDF(2.685452001065306445309714835481795693820)
 
 
@@ -772,5 +672,5 @@
     """
     def __init__(self):
-        Constant.__init__(self,{'maxima':'twinprime'}) #Twin prime is not implemented in any other algebra systems.
+        Constant.__init__(self,{}) #Twin prime is not implemented in any other algebra systems.
 	
         #digits come from http://www.gn-50uma.de/alula/essays/Moree/Moree-details.en.shtml
@@ -783,5 +683,5 @@
         return Integer(0)
 
-    def _repr_(self, simplify=True):
+    def _repr_(self):
         return 'twinprime'
 
@@ -791,5 +691,5 @@
         raise NotImplementedError, "Twin Prime constant only available up to %s bits"%self.__bits
 
-    def _real_double_(self, R):
+    def _real_double_(self):
         """
         EXAMPLES:
@@ -797,5 +697,5 @@
             0.660161815847
         """
-	return R('0.660161815846869573927812110014555778432')
+	return sage.rings.all.RDF(0.660161815846869573927812110014555778432)
 
     def __float__(self):
@@ -824,5 +724,5 @@
     """
     def __init__(self):
-        Constant.__init__(self,{'maxima':'merten'}) #Merten's constant is not implemented in any other algebra systems.
+        Constant.__init__(self,{}) #Merten's constant is not implemented in any other algebra systems.
 
         # digits come from Sloane's tables at http://www.research.att.com/~njas/sequences/table?a=77761&fmt=0
@@ -835,5 +735,5 @@
         return Integer(0)
 
-    def _repr_(self, simplify=True):
+    def _repr_(self):
         return 'merten'
 
@@ -852,5 +752,5 @@
         raise NotImplementedError, "Merten's constant only available up to %s bits"%self.__bits
 
-    def _real_double_(self, R):
+    def _real_double_(self):
         """
         EXAMPLES:
@@ -858,5 +758,5 @@
             0.261497212848
         """
-        return R('0.261497212847642783755426838608695859051')
+        return sage.rings.all.RDF(0.261497212847642783755426838608695859051)
 
     def __float__(self):
@@ -867,5 +767,4 @@
         """
 	return 0.261497212847642783755426838608695859051
-
 
 merten = Merten()
@@ -888,5 +787,5 @@
     """
     def __init__(self):
-        Constant.__init__(self,{'maxima':"brun"}) #Brun's constant is not implemented in any other algebra systems.
+        Constant.__init__(self,{}) #Brun's constant is not implemented in any other algebra systems.
 
         # digits come from Sloane's tables at http://www.research.att.com/~njas/sequences/table?a=65421&fmt=0
@@ -899,5 +798,5 @@
         return Integer(1)
 
-    def _repr_(self, simplify=True):
+    def _repr_(self):
         return 'brun'
 
@@ -916,5 +815,5 @@
         raise NotImplementedError, "Brun's constant only available up to %s bits"%self.__bits
 
-    def _real_double_(self, R):
+    def _real_double_(self):
         """
         EXAMPLES:
@@ -922,5 +821,5 @@
             1.9021605831
         """
-        return R('1.9021605831040')
+        return sage.rings.all.RDF(1.9021605831040)
 
     def __float__(self):
@@ -934,2 +833,49 @@
 brun=Brun()
 
+class UniversalPolynomialElement(Constant):
+    """
+    A universal indeterminate.
+    
+    EXAMPLES:
+        sage: x
+        x
+        sage: x.parent()
+        Univariate Polynomial Ring in x over Rational Field
+    """
+    def __init__(self, name):
+        self._name = name
+        Constant.__init__(self,
+            {'axiom':name, 
+             'maxima':name,
+             'gp':name,'kash':name,
+             'mathematica':name,
+             'matlab':name,
+             'maple':name,
+             'octave':name,
+             'pari':name})
+        
+    def _repr_(self):
+        return self._name
+
+    def _latex_(self):
+        return self._name
+
+    def _mathml_(self):
+        return "<mi>%s</mi>"%self._name
+
+    def __float__(self):
+        raise TypeError
+
+    def _mpfr_(self, R):
+        raise TypeError
+
+    def _real_double_(self):
+        raise TypeError
+
+    def __abs__(self):
+        raise TypeError
+
+    def floor(self):
+        raise TypeError
+
+x = UniversalPolynomialElement('x')
Index: sage/functions/functions.py
===================================================================
--- sage/functions/functions.py	(revision 4061)
+++ sage/functions/functions.py	(revision 3290)
@@ -2,4 +2,14 @@
 SAGE Functions Class
 
+EXAMPLES:
+    sage: f = 5*sin(x)
+    sage: f
+    (5*sin(x))
+    sage: f(2)
+    (5*sin(2))
+    sage: f(pi)
+    (5*sin(((1*pi) + 0)))
+    sage: float(f(pi))
+    6.1232339957367663e-16
 """
 import weakref
@@ -103,4 +113,6 @@
 
     def _coerce_impl(self, x):
+        if is_Polynomial(x):
+            return self(x)
         return self(x)
 
@@ -206,6 +218,11 @@
         """
         EXAMPLES:
-            sage: s = singular(e); s
+            sage: singular(e)
             2.71828182845905
+            sage: P = e.parent()
+            sage: old_prec = P.set_precision(200)
+            sage: singular(e)
+            2.7182818284590452353602874713526624977572470936999595749670
+            sage: _ = P.set_precision(old_prec)
         """
         try:
@@ -247,16 +264,16 @@
         EXAMPLES:
             sage: s = e + pi
-            sage: bool(s == 0)
+            sage: s == 0
             False
             sage: t = e^2  +pi
-            sage: bool(s == t)
+            sage: s == t
             False
-            sage: bool(s == s)
+            sage: s == s
             True
-            sage: bool(t == t)
+            sage: t == t
             True
-            sage: bool(s < t)
+            sage: s < t
             True
-            sage: bool(t < s)
+            sage: t < s
             False
         """
@@ -318,18 +335,18 @@
         sage: s = (pi + pi) * e + e
         sage: s
-        2*e*pi + e
+        (((pi + pi)*e) + e)
         sage: RR(s)
         19.7977502738062
         sage: maxima(s)
-        2*%e*%pi+%e
+        2*%e*%pi + %e
 
         sage: t = e^2 + pi + 2/3; t
-        pi + e^2 + 2/3
+        (((e^2) + pi) + 2/3)
         sage: RR(t)
         11.1973154191871
         sage: maxima(t)
-        %pi+%e^2+2/3
+        %pi + %e^2 + 2/3
         sage: t^e
-        (pi + e^2 + 2/3)^e
+        ((((e^2) + pi) + 2/3)^e)
         sage: RR(t^e)
         710.865247688858
@@ -343,16 +360,9 @@
         self.__op = op  # a binary operator, e.g., operator.sub
 
-    def _maxima_init_(self):
-        x = self.__x
-        y = self.__y
-        op = self.__op
-        return '(%s) %s (%s)'%(x._maxima_init_(), symbols[op] ,y._maxima_init_())
-            
-
     def _repr_(self):
         """
         EXAMPLES:
             sage: log2 * e + pi^2/2
-            e*log(2) + pi^2/2
+            ((log2*e) + ((pi^2)/2))
         """
         return '(%s%s%s)'%(self.__x, symbols[self.__op], self.__y)
@@ -362,9 +372,9 @@
         EXAMPLES:
             sage: latex(log2 * e + pi^2/2)
-            {e \cdot \log \left( 2 \right)} + \frac{{\pi}^{2} }{2}
+            \log(2) \cdot e + \frac{\pi^{2}}{2}
             sage: latex(NaN^3 + 1/golden_ratio)
-            {\text{NaN}}^{3}  + \frac{2}{\sqrt{ 5 } + 1}
+            \text{NaN}^{3} + \frac{1}{\phi}
             sage: latex(log2 + euler_gamma + catalan + khinchin + twinprime + merten + brun)
-            \text{twinprime} + \text{merten} + \text{khinchin} + \gamma + \text{catalan} + \text{brun} + \log \left( 2 \right)
+            \log(2) + \gamma + K + \text{khinchin} + \text{twinprime} + \text{merten} + \text{brun}
         """
         if self.__op == operator.div:
@@ -390,5 +400,5 @@
         EXAMPLES:
             sage: gap(e + pi)
-            "pi + e"
+            "5.85987448204884"
         """
         return '"%s"'%self.str()
@@ -431,5 +441,5 @@
         EXAMPLES:
             sage: maxima(e + pi)
-            %pi+%e
+            %pi + %e
         """
         return self.__op(self.__x._maxima_(maxima), self.__y._maxima_(maxima)) 
@@ -459,5 +469,5 @@
         EXAMPLES:
             sage: singular(e + pi)
-            pi + e
+            5.85987448204884
         """
         return '"%s"'%self.str()
@@ -480,7 +490,7 @@
         sage: a = pi/2 + e
         sage: a
-        pi/2 + e
+        ((pi/2) + e)
         sage: maxima(a)
-        %pi/2+%e
+        %pi/2 + %e
         sage: RR(a)
         4.28907815525394
@@ -490,5 +500,5 @@
         sage: b = e + 5/7
         sage: maxima(b)
-        %e+5/7
+        %e + 5/7
         sage: RR(b)
         3.43256754274476
Index: sage/functions/orthogonal_polys.py
===================================================================
--- sage/functions/orthogonal_polys.py	(revision 4016)
+++ sage/functions/orthogonal_polys.py	(revision 3301)
@@ -386,9 +386,9 @@
         sage: t = PolynomialRing(QQ, "t").gen()
         sage: gen_legendre_P(2,0,t)
-        '3*(1-t)^2/2-3*(1-t)+1'
+        '3*(1 - t)^2/2 - 3*(1 - t) + 1'
         sage: legendre_P(2,t)
         3/2*t^2 - 1/2
         sage: gen_legendre_P(3,1,t)
-        '-6*(5*(1-t)^2/4-5*(1-t)/2+1)*sqrt(1-t^2)'
+        '-6*(5*(1 - t)^2/4 - 5*(1 - t)/2 + 1)*sqrt(1 - t^2)'
     """
     _init()
@@ -412,7 +412,7 @@
         sage: t = PolynomialRing(QQ, "t").gen()
         sage: gen_legendre_Q(2,0,t)
-        '(3*log(-(t+1)/(t-1))*t^2-6*t-log(-(t+1)/(t-1)))/4'
+        '(3*log( - (t + 1)/(t - 1))*t^2 - 6*t - log( - (t + 1)/(t - 1)))/4'
         sage: legendre_Q(2,t)
-        '(3*log(-(t+1)/(t-1))*t^2-6*t-log(-(t+1)/(t-1)))/4'
+        '(3*log( - (t + 1)/(t - 1))*t^2 - 6*t - log( - (t + 1)/(t - 1)))/4'
         sage: gen_legendre_Q(3,1,0.5)
         2.49185259171
@@ -523,5 +523,5 @@
         sage: t = PolynomialRing(QQ, 't').gen()
         sage: legendre_Q(2,t)
-        '(3*log(-(t+1)/(t-1))*t^2-6*t-log(-(t+1)/(t-1)))/4'
+        '(3*log( - (t + 1)/(t - 1))*t^2 - 6*t - log( - (t + 1)/(t - 1)))/4'
         sage: legendre_Q(3,0.5)
         -0.198654771479
Index: sage/functions/piecewise.py
===================================================================
--- sage/functions/piecewise.py	(revision 4058)
+++ sage/functions/piecewise.py	(revision 3636)
@@ -99,12 +99,4 @@
 from sage.rings.all import QQ, RR, Integer, Rational
 
-from sage.interfaces.maxima import maxima
-from sage.calculus.calculus import SR, var
-
-def meval(x):
-    from sage.calculus.calculus import symbolic_expression_from_maxima_element
-    return symbolic_expression_from_maxima_element(maxima(x))
-
-
 class PiecewisePolynomial:
     def __init__(self, list_of_pairs):
@@ -141,4 +133,5 @@
             sage: f.latex()
             '\\begin{array}{ll} \\left\\{ 1,& 0 < x < 1 ,\\right. \\end{array}'
+
 	"""
         x = PolynomialRing(QQ,'x').gen()
@@ -150,5 +143,5 @@
 	    a = intvls[i][0]
 	    b = intvls[i][1]
-            tex.append(repr(f(x)))
+            tex.append(str(f(x)))
 	    tex.append(",& %s < x < %s ,\\"%(a,b))
         tex = tex[:-2]
@@ -434,19 +427,18 @@
     def critical_points(self):
         """
-        Return the critical points of this piecewise function.
-
-        WARNINGS: Uses maxima, which prints the warning to use results
-        with caution. Only works for piecewise functions whose parts
-        are polynomials with real critical not occurring on the
-        interval endpoints.
+        Function to return the critical points. Uses maxima, which
+        prints the warning to use results with caution. Only works for
+        piecewise functions whose parts are polynomials with real
+        critical not occurring on the interval endpoints.
 
         EXAMPLES:
             sage: x = PolynomialRing(QQ, 'x').0
             sage: f1 = x^0
-            sage: f2 = 10*x - x^2
-            sage: f3 = 3*x^4 - 156*x^3 + 3036*x^2 - 26208*x
-            sage: f = Piecewise([[(0,3),f1],[(3,10),f2],[(10,20),f3]])
+            sage: f2 = 1-x
+            sage: f3 = 2*x
+            sage: f4 = 10*x-x^2
+            sage: f = Piecewise([[(0,1),f1],[(1,2),f2],[(2,3),f3],[(3,10),f4]])
             sage: f.critical_points()
-            [5.0, 12.000000000000171, 12.9999999999996, 14.000000000000229]
+            [5.0]
         """
         maxima = sage.interfaces.all.maxima
@@ -455,20 +447,13 @@
         N = len(fcns)
         crit_pts = []
-        I = self.intervals()
         for i in range(N):
             maxima.eval("eqn:diff(%s,x)=0"%fcns[i])
             ans = maxima.eval("allroots(eqn)")
-            while True:
-                start = ans.find('x=')
-                if start == -1:
-                    break
-                ans = ans[start+2:]
-                end = ans.find(',')
-                if end == -1:
-                    end = ans.find(']')
-                r = float(ans[:end])
-                if I[i][0] < r < I[i][1]:
+            if "[x =" in ans:
+                i1 = ans.index("[x =")
+                i2 = ans.index("]")
+                r = eval(ans[i1+4:i2])
+                if self.intervals()[i][0] < r < self.intervals()[i][1]:
                     crit_pts.append(r)
-                ans = ans[end+1:]
         return crit_pts
 
@@ -565,11 +550,11 @@
             sage: f = Piecewise([[(0,pi/2),f1],[(pi/2,pi),f2]])
             sage: f.integral()
-            pi/2
+            (pi/2)
         """
         maxima = sage.interfaces.all.maxima
         x = PolynomialRing(QQ,'x').gen()
         ints = [maxima('%s'%p[1](x)).integral('x', p[0][0], p[0][1]) \
-                 for p in self.list()]
-        return meval(repr(sum(ints)))
+                 for p in self.list()]  
+        return sage_eval(str(sum(ints)).replace("%",""))
 
     def convolution(self,other):
@@ -611,5 +596,5 @@
         R1 = f0.parent()
         xx = R1.gen()
-        var = repr(xx)
+        var = str(xx)
         if len(f.intervals())==1 and len(g.intervals())==1:
             f = f.unextend()
@@ -619,6 +604,6 @@
             b1 = g.intervals()[0][0]
             b2 = g.intervals()[0][1]
-            i1 = repr(f0).replace(var,repr(uu))
-            i2 = repr(g0).replace(var,"("+repr(tt-uu)+")")
+            i1 = str(f0).replace(var,str(uu))
+            i2 = str(g0).replace(var,"("+str(tt-uu)+")")
             cmd1 = "integrate((%s)*(%s),%s,%s,%s)"%(i1,i2, uu, a1,    tt-b1)    ## if a1+b1 < tt < a2+b1
             cmd2 = "integrate((%s)*(%s),%s,%s,%s)"%(i1,i2, uu, tt-b2, tt-b1)    ## if a1+b2 < tt < a2+b1
@@ -629,10 +614,8 @@
             conv3 = maxima.eval(cmd3)
             conv4 = maxima.eval(cmd4)
-            # this is a very, very, very ugly hack
-            x = PolynomialRing(QQ,'x').gen()
-            fg1 = sage_eval(conv1.replace("tt",var), {'x':x}) ## should be = R2(conv1)
-            fg2 = sage_eval(conv2.replace("tt",var), {'x':x}) ## should be = R2(conv2)
-            fg3 = sage_eval(conv3.replace("tt",var), {'x':x}) ## should be = R2(conv3)
-            fg4 = sage_eval(conv4.replace("tt",var), {'x':x}) ## should be = R2(conv4)
+            fg1 = sage_eval(conv1.replace("tt",var)) ## should be = R2(conv1)
+            fg2 = sage_eval(conv2.replace("tt",var)) ## should be = R2(conv2)
+            fg3 = sage_eval(conv3.replace("tt",var)) ## should be = R2(conv3)
+            fg4 = sage_eval(conv4.replace("tt",var)) ## should be = R2(conv4)
             if a1-b1<a2-b2:
                 if a2+b1!=a1+b2:
@@ -645,6 +628,6 @@
                 else:
                     h = Piecewise([[(a1+b1,a2+b1),fg1],[(a2+b1,a2+b2),fg3]])
+            #return h.unextend()
             return h
-        
         if len(f.intervals())>1 or len(g.intervals())>1:
             z = Piecewise([[(-3*abs(N-M),3*abs(N-M)),0*xx**0]])
@@ -677,5 +660,5 @@
             sage: f = Piecewise([[(0,pi/2),f1],[(pi/2,pi),f2]])
             sage: f.derivative()
-            Piecewise defined function with 2 parts, [[(0, pi/2), 0], [(pi/2, pi), 0]]
+            Piecewise defined function with 2 parts, [[(0, (pi/2)), 0], [((pi/2), pi), 0]]
         """
         maxima = sage.interfaces.all.maxima
@@ -684,7 +667,5 @@
         diffs = [maxima('%s'%p[1](x)).diff('x') \
                  for p in self.list()]  
-        dlist = [[(p[0][0], p[0][1]),
-            R(sage_eval(repr(maxima('%s'%p[1](x)).diff('x')).replace("%",""),
-                {'x':x}))] for p in self.list()]
+        dlist = [[(p[0][0], p[0][1]), R(sage_eval(str(maxima('%s'%p[1](x)).diff('x')).replace("%","")))] for p in self.list()]
         return Piecewise(dlist)
  
@@ -749,5 +730,5 @@
             sage: f = Piecewise([[(-1,1),f]])
             sage: f.fourier_series_cosine_coefficient(2,1)
-            1/pi^2
+            (1/(pi^2))
 	    sage: f = lambda x:x^2
             sage: f = Piecewise([[(-pi,pi),f]])
@@ -758,5 +739,5 @@
             sage: f = Piecewise([[(0,pi/2),f1],[(pi/2,pi),f2]])
             sage: f.fourier_series_cosine_coefficient(5,pi)
-            -3/(5*pi)
+            (-3/(5*pi))
         """
         maxima = sage.interfaces.all.maxima
@@ -766,11 +747,11 @@
             fcn = '(%s)*cos('%p[1](x) + 'pi*x*%s/%s)/%s'%(n,L,L)
             fcn = fcn.replace("pi","%"+"pi")
-	    a = repr(p[0][0]).replace("pi","%"+"pi")
-	    b = repr(p[0][1]).replace("pi","%"+"pi")
+	    a = str(p[0][0]).replace("pi","%"+"pi")
+	    b = str(p[0][1]).replace("pi","%"+"pi")
 	    cmd = "integrate("+fcn+", x, %s, %s )"%(a, b)
 	    int = maxima(cmd).trigsimp()
             ints.append(int)
         ans = sum(ints)
-        return meval(repr(ans))
+        return sage_eval(str(ans).replace("%",""))
 
     def fourier_series_sine_coefficient(self,n,L):
@@ -798,11 +779,11 @@
             fcn = '(%s)*sin('%p[1](x) + 'pi*x*%s/%s)/%s'%(n,L,L)
             fcn = fcn.replace("pi","%"+"pi")
-	    a = repr(p[0][0]).replace("pi","%"+"pi")
-	    b = repr(p[0][1]).replace("pi","%"+"pi")
+	    a = str(p[0][0]).replace("pi","%"+"pi")
+	    b = str(p[0][1]).replace("pi","%"+"pi")
 	    cmd = "integrate("+fcn+", x, %s, %s )"%(a, b)
 	    int = maxima(cmd).trigsimp()
             ints.append(int)
         ans = sum(ints)
-        return meval(repr(ans))
+        return sage_eval(str(ans).replace("%",""))
 
     def fourier_series_partial_sum(self,N,L):
@@ -819,19 +800,20 @@
             sage: f = Piecewise([[(-1,1),f]])
             sage: f.fourier_series_partial_sum(3,1)
-            cos(2*pi*x)/pi^2 - (4*cos(pi*x)/pi^2) + 1/3
+            '1/3 + ((-4/(pi^2))*cos(1*pi*x/1) + 0*sin(1*pi*x/1)) + ((1/(pi^2))*cos(2*pi*x/1) + 0*sin(2*pi*x/1))'
             sage: f1 = lambda x:-1
             sage: f2 = lambda x:2
             sage: f = Piecewise([[(0,pi/2),f1],[(pi/2,pi),f2]])
             sage: f.fourier_series_partial_sum(3,pi)
-            -3*sin(2*x)/pi + sin(x)/pi - (3*cos(x)/pi) + 1/4
+            '1/4 + ((-3/pi)*cos(1*pi*x/pi) + (1/pi)*sin(1*pi*x/pi)) + (0*cos(2*pi*x/pi) + (-3/pi)*sin(2*pi*x/pi))'
+
         """
         a0 = self.fourier_series_cosine_coefficient(0,L)
-        A = [repr(self.fourier_series_cosine_coefficient(n,L))+"*cos(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
-        B = [repr(self.fourier_series_sine_coefficient(n,L))+"*sin(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
+        A = [str(self.fourier_series_cosine_coefficient(n,L))+"*cos(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
+        B = [str(self.fourier_series_sine_coefficient(n,L))+"*sin(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
         FS =  ["("+A[i] +" + " + B[i]+")" for i in range(0,N-1)]
-        sumFS = repr(a0/2)+" + "
+        sumFS = str(a0/2)+" + "
         for s in FS:
             sumFS = sumFS+s+ " + "
-        return meval(sumFS[:-3])
+        return sumFS[:-3]
   
     def fourier_series_partial_sum_cesaro(self,N,L):
@@ -848,20 +830,20 @@
             sage: f = Piecewise([[(-1,1),f]])
             sage: f.fourier_series_partial_sum_cesaro(3,1)
-            cos(2*pi*x)/(3*pi^2) - (8*cos(pi*x)/(3*pi^2)) + 1/3
+            '1/3 + ((2/3*(-4/(pi^2)))*cos(1*pi*x/1) + 0*sin(1*pi*x/1)) + ((1/3*(1/(pi^2)))*cos(2*pi*x/1) + 0*sin(2*pi*x/1))'
             sage: f1 = lambda x:-1
             sage: f2 = lambda x:2
             sage: f = Piecewise([[(0,pi/2),f1],[(pi/2,pi),f2]])
             sage: f.fourier_series_partial_sum_cesaro(3,pi)
-            -sin(2*x)/pi + 2*sin(x)/(3*pi) - (2*cos(x)/pi) + 1/4
+            '1/4 + ((2/3*(-3/pi))*cos(1*pi*x/pi) + (2/3*(1/pi))*sin(1*pi*x/pi)) + (0*cos(2*pi*x/pi) + (1/3*(-3/pi))*sin(2*pi*x/pi))'
 
         """
         a0 = self.fourier_series_cosine_coefficient(0,L)
-        A = [repr((1-n/N)*self.fourier_series_cosine_coefficient(n,L))+"*cos(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
-        B = [repr((1-n/N)*self.fourier_series_sine_coefficient(n,L))+"*sin(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
+        A = [str((1-n/N)*self.fourier_series_cosine_coefficient(n,L))+"*cos(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
+        B = [str((1-n/N)*self.fourier_series_sine_coefficient(n,L))+"*sin(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
         FS =  ["("+A[i] +" + " + B[i]+")" for i in range(0,N-1)]
-        sumFS = repr(a0/2)+" + "
+        sumFS = str(a0/2)+" + "
         for s in FS:
             sumFS = sumFS+s+ " + "
-        return meval(sumFS[:-3])
+        return sumFS[:-3]
 
     def fourier_series_partial_sum_hann(self,N,L):
@@ -878,19 +860,20 @@
             sage: f = Piecewise([[(-1,1),f]])
             sage: f.fourier_series_partial_sum_hann(3,1)
-            0.500000000000000*(cos(2*pi/3) + 1)*cos(2*pi*x)/pi^2 - (2.00000000000000*(cos(pi/3) + 1)*cos(pi*x)/pi^2) + 1/3
+            '1/3 + ((1+cos(pi*1/3))*(0.5*(-4/(pi^2)))*cos(1*pi*x/1) + (1+cos(pi*1/3))*0.0*sin(1*pi*x/1)) + ((1+cos(pi*2/3))*(0.5*(1/(pi^2)))*cos(2*pi*x/1) + (1+cos(pi*2/3))*0.0*sin(2*pi*x/1))'
             sage: f1 = lambda x:-1
             sage: f2 = lambda x:2
             sage: f = Piecewise([[(0,pi/2),f1],[(pi/2,pi),f2]])
             sage: f.fourier_series_partial_sum_hann(3,pi)
-            -1.50000000000000*(cos(2*pi/3) + 1)*sin(2*x)/pi + 0.500000000000000*(cos(pi/3) + 1)*sin(x)/pi - (1.50000000000000*(cos(pi/3) + 1)*cos(x)/pi) + 1/4
+            '1/4 + ((1+cos(pi*1/3))*(0.5*(-3/pi))*cos(1*pi*x/pi) + (1+cos(pi*1/3))*(0.5*(1/pi))*sin(1*pi*x/pi)) + ((1+cos(pi*2/3))*0.0*cos(2*pi*x/pi) + (1+cos(pi*2/3))*(0.5*(-3/pi))*sin(2*pi*x/pi))'
+
         """
         a0 = self.fourier_series_cosine_coefficient(0,L)
-        A = ["(1+cos(pi*%s/%s))*"%(n,N)+repr((0.5)*self.fourier_series_cosine_coefficient(n,L))+"*cos(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
-        B = ["(1+cos(pi*%s/%s))*"%(n,N)+repr((0.5)*self.fourier_series_sine_coefficient(n,L))+"*sin(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
+        A = ["(1+cos(pi*%s/%s))*"%(n,N)+str((0.5)*self.fourier_series_cosine_coefficient(n,L))+"*cos(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
+        B = ["(1+cos(pi*%s/%s))*"%(n,N)+str((0.5)*self.fourier_series_sine_coefficient(n,L))+"*sin(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
         FS =  ["("+A[i] +" + " + B[i]+")" for i in range(0,N-1)]
-        sumFS = repr(a0/2)+" + "
+        sumFS = str(a0/2)+" + "
         for s in FS:
             sumFS = sumFS+s+ " + "
-        return meval(sumFS[:-3])
+        return sumFS[:-3]
 
     def fourier_series_partial_sum_filtered(self,N,L,F):
@@ -908,19 +891,20 @@
             sage: f = Piecewise([[(-1,1),f]])
             sage: f.fourier_series_partial_sum_filtered(3,1,[1,1,1])
-            cos(2*pi*x)/pi^2 - (4*cos(pi*x)/pi^2) + 1/3
+            '1/3 + ((1*(-4/(pi^2)))*cos(1*pi*x/1) + 0*sin(1*pi*x/1)) + ((1*(1/(pi^2)))*cos(2*pi*x/1) + 0*sin(2*pi*x/1))'
             sage: f1 = lambda x:-1
             sage: f2 = lambda x:2
             sage: f = Piecewise([[(0,pi/2),f1],[(pi/2,pi),f2]])
             sage: f.fourier_series_partial_sum_filtered(3,pi,[1,1,1])
-            -3*sin(2*x)/pi + sin(x)/pi - (3*cos(x)/pi) + 1/4
+            '1/4 + ((1*(-3/pi))*cos(1*pi*x/pi) + (1*(1/pi))*sin(1*pi*x/pi)) + (0*cos(2*pi*x/pi) + (1*(-3/pi))*sin(2*pi*x/pi))'
+
         """
         a0 = self.fourier_series_cosine_coefficient(0,L)
-        A = [repr((F[n])*self.fourier_series_cosine_coefficient(n,L))+"*cos(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
-        B = [repr((F[n])*self.fourier_series_sine_coefficient(n,L))+"*sin(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
+        A = [str((F[n])*self.fourier_series_cosine_coefficient(n,L))+"*cos(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
+        B = [str((F[n])*self.fourier_series_sine_coefficient(n,L))+"*sin(%s*pi*x/%s)"%(n,L) for n in range(1,N)]
         FS =  ["("+A[i] +" + " + B[i]+")" for i in range(0,N-1)]
-        sumFS = repr(a0/2)+" + "
+        sumFS = str(a0/2)+" + "
         for s in FS:
             sumFS = sumFS+s+ " + "
-        return meval(sumFS[:-3])
+        return sumFS[:-3]
 	
     def plot_fourier_series_partial_sum(self,N,L,xmin,xmax, **kwds):
@@ -957,6 +941,6 @@
             pi = 3.14159265
             xi = xmin + i*h
-            yi = ff.replace("pi",repr(RR(pi)))
-            yi = sage_eval(yi.replace("x",repr(xi)))
+            yi = ff.replace("pi",str(RR(pi)))
+            yi = sage_eval(yi.replace("x",str(xi)))
             pts.append([xi,yi])
         return line(pts, **kwds)
@@ -995,6 +979,6 @@
             pi = 3.14159265
             xi = xmin + i*h
-            yi = ff.replace("pi",repr(RR(pi)))
-            yi = sage_eval(yi.replace("x",repr(xi)))
+            yi = ff.replace("pi",str(RR(pi)))
+            yi = sage_eval(yi.replace("x",str(xi)))
             pts.append([xi,yi])
         return line(pts, **kwds)
@@ -1033,6 +1017,6 @@
             pi = 3.14159265
             xi = xmin + i*h
-            yi = ff.replace("pi",repr(RR(pi)))
-            yi = sage_eval(yi.replace("x",repr(xi)))
+            yi = ff.replace("pi",str(RR(pi)))
+            yi = sage_eval(yi.replace("x",str(xi)))
             pts.append([xi,yi])
         return line(pts, **kwds)
@@ -1073,6 +1057,6 @@
             pi = 3.14159265
             xi = xmin + i*h
-            yi = ff.replace("pi",repr(RR(pi)))
-            yi = sage_eval(yi.replace("x",repr(xi)))
+            yi = ff.replace("pi",str(RR(pi)))
+            yi = sage_eval(yi.replace("x",str(xi)))
             pts.append([xi,yi])
         return line(pts, **kwds)
@@ -1155,5 +1139,5 @@
             0
             sage: f.cosine_series_coefficient(3,1)
-            -4/(9*pi^2)
+            (-4/(9*(pi^2)))
             sage: f1 = lambda x:-1
             sage: f2 = lambda x:2
@@ -1162,7 +1146,7 @@
             0
             sage: f.cosine_series_coefficient(3,pi)
-            2/pi
+            (2/pi)
             sage: f.cosine_series_coefficient(111,pi)
-            2/(37*pi)
+            (2/(37*pi))
 
         """
@@ -1173,12 +1157,11 @@
             fcn = '2*(%s)*cos('%p[1](x) + 'pi*x*%s/%s)/%s'%(n,L,L)
             fcn = fcn.replace("pi","%"+"pi")
-	    a = repr(p[0][0]).replace("pi","%"+"pi")
-	    b = repr(p[0][1]).replace("pi","%"+"pi")
+	    a = str(p[0][0]).replace("pi","%"+"pi")
+	    b = str(p[0][1]).replace("pi","%"+"pi")
 	    cmd = "integrate("+fcn+", x, %s, %s )"%(a, b)
 	    I = maxima(cmd).trigsimp()
             ints.append(I)
         ans = sum(ints)
-        return meval(repr(ans))
-
+        return sage_eval(str(ans).replace("%",""))
 
     def sine_series_coefficient(self,n,L):
@@ -1204,5 +1187,6 @@
             0
             sage: f.sine_series_coefficient(3,1)
-            4/(3*pi)
+            (4/(3*pi))
+
         """
 	maxima = sage.interfaces.all.maxima
@@ -1212,48 +1196,54 @@
             fcn = '2*(%s)*sin('%p[1](x) + 'pi*x*%s/%s)/%s'%(n,L,L)
             fcn = fcn.replace("pi","%"+"pi")
-	    a = repr(p[0][0]).replace("pi","%"+"pi")
-	    b = repr(p[0][1]).replace("pi","%"+"pi")
+	    a = str(p[0][0]).replace("pi","%"+"pi")
+	    b = str(p[0][1]).replace("pi","%"+"pi")
 	    cmd = "integrate("+fcn+", x, %s, %s )"%(a, b)
 	    I = maxima(cmd).trigsimp()
             ints.append(I)
         ans = sum(ints)
-        return meval(repr(ans))
-
-    def laplace(self, x, s):
-        r"""
-        Returns the Laplace transform of self with respect to the
-        variable var.
-
-        INPUT:
-            x -- variable of self
-            s -- variable of Laplace transform.
-
+        return sage_eval(str(ans).replace("%",""))
+
+    def laplace_transform(self,var = "s",latex_output=0):
+        r"""
+        Returns the laplace transform of self, as a function of var.
         We assume that a piecewise function is 0 outside of its domain
         and that the left-most endpoint of the domain is 0.
 
         EXAMPLES:
-            sage: f = Piecewise([[(0,1),1],[(1,2), 1-x]])
-            sage: f.laplace(x, s)
-            -e^(-s)/s - (e^(-s)/s^2) + (s + 1)*e^(-2*s)/s^2 + 1/s
-            sage: f.laplace(x, w)
-            -e^(-w)/w - (e^(-w)/w^2) + (w + 1)*e^(-2*w)/w^2 + 1/w
-
-            sage: f = Piecewise([[(1,2), 1-y]]) 
-            sage: f.laplace(y, t)
-            (t + 1)*e^(-2*t)/t^2 - (e^(-t)/t^2)
-        """
-        x = var(x)
-        s = var(s)
+            sage: f1 = lambda x:1
+            sage: f2 = lambda x:1-x
+            sage: f = Piecewise([[(0,1),f1],[(1,2),f2]])
+            sage: f.laplace_transform()
+            '1/s - e^-s/s + (s + 1)*e^-(2*s)/s^2 - e^-s/s^2'
+            sage: f.laplace_transform("w",latex_output=1)
+            ' - {{e^{ - w}}\\over{w}} - {{e^{ - w}}\\over{w^2}} + {{\\left(w + 1\\right)\\,e^{ - 2\\,w}}\\over{w^2}} + {{1}\\over{w}}'
+            sage: f.laplace_transform("w",True)
+            ' - {{e^{ - w}}\\over{w}} - {{e^{ - w}}\\over{w^2}} + {{\\left(w + 1\\right)\\,e^{ - 2\\,w}}\\over{w^2}} + {{1}\\over{w}}'
+            sage: f.laplace_transform("w")
+            '1/w - e^-w/w + (w + 1)*e^-(2*w)/w^2 - e^-w/w^2'
+
+        """
+        maxima = sage.interfaces.all.maxima
+        x = PolynomialRing(QQ,'x').gen()
         ints = []
         for p in self.list():
-            g = SR(p[1])
-            fcn = maxima('(%s)*exp(-%s*%s)'%(g._maxima_init_(), s, x))
-            ints.append(fcn.integral(x, p[0][0], p[0][1]))
+            fcn = '(%s)*exp(-%s*x)'%(p[1](x),var)
+            ints.append(maxima(fcn).integral('x', p[0][0], p[0][1]))  
         ans = ""
+        ans_latex = ""
         for i in range(len(ints)-1):
-            ans = ans+repr(ints[i]) + " + "
-        ans = ans+repr(ints[len(ints)-1])
-        return meval(ans)
-    
+            ans = ans+str(ints[i]).replace("%","")+" + "
+            ans_latex = ans_latex+str(ints[i])+" + "
+        ans = ans+str(ints[len(ints)-1]).replace("%","")
+        ans_latex = ans_latex + str(ints[len(ints)-1])
+        
+        if latex_output == 0:
+            return ans
+        if latex_output == 1:
+            ans0 = maxima.eval("tex("+ans_latex+")")
+            ans0 = ans0.replace("$$","")
+            ans0 = ans0.replace("false","")
+            return ans0
+
     def __add__(self,other):
 	"""
Index: sage/functions/special.py
===================================================================
--- sage/functions/special.py	(revision 4053)
+++ sage/functions/special.py	(revision 2641)
@@ -1,3 +1,3 @@
-r"""
+r"""nodoctest -- TODO remove
 Special Functions
 
@@ -5,6 +5,5 @@
    -- David Joyner (2006-13-06)
 
-This module provides easy access to many of Maxima and PARI's
-special functions.
+Some of Maxima's and Pari's special functions are wrapped.
 
 Maxima's special functions package (which includes spherical harmonic
@@ -332,17 +331,12 @@
 from sage.rings.rational_field import RationalField
 from sage.rings.real_mpfr import RealField
-from sage.rings.complex_field import ComplexField
 from sage.misc.sage_eval import sage_eval
-from sage.rings.all import ZZ, QQ, RR
+from sage.rings.all import QQ, RR
 import sage.rings.commutative_ring as commutative_ring
 import sage.rings.ring as ring
 
-from sage.interfaces.maxima import maxima
-
-def meval(x):
-    from sage.calculus.calculus import symbolic_expression_from_maxima_element
-    return symbolic_expression_from_maxima_element(maxima(x))
-
 from functions import *
+
+from sage.misc.functional import exp
 
 _done = False
@@ -361,9 +355,4 @@
     return RR, a
 
-def _setup_CC(prec):
-    from sage.libs.pari.all import pari
-    CC = ComplexField(prec) 
-    a = pari.set_real_precision(int(prec/3.3)+1)    ## 3.3 < log(10,2)
-    return CC, a
 
 def bessel_I(nu,z,alg = "pari",prec=53):
@@ -410,7 +399,7 @@
     EXAMPLES:
         sage: bessel_I(1,1,"pari",500)
-        0.565159103992485027207696027609863307328899621621092009480294489479255640964371134092664997766814410064677886055526302676857637684917179812041131208121
+        0.56515910399248502720769602760986330732889962162109200948029448947925564096437113409266499776681441006467788605552630267685763768491717981204113120812118
         sage: bessel_I(1,1)
-        0.565159103992485
+        0.56515910399248503
         sage: bessel_I(2,1.1,"maxima")  # last few digits are random
         0.16708949925104899
@@ -427,5 +416,5 @@
         return b
     else:
-        return sage_eval(maxima.eval("bessel_i(%s,%s)"%(float(nu),float(z))))
+        return eval(maxima.eval("bessel_i(%s,%s)"%(float(nu),float(z))))
         
 def bessel_J(nu,z,alg="pari",prec=53):
@@ -484,12 +473,10 @@
     if alg=="pari":
         from sage.libs.pari.all import pari
-        K,a = _setup(prec)
-        if not (z in K):
-            K, a = _setup_CC(prec)
-        b = K(pari(z).besselj(nu))
+        R,a = _setup(prec)
+        b = R(pari(z).besselj(nu))
         pari.set_real_precision(a)
         return b
     else:
-        return meval("bessel_j(%s,%s)"%(nu, z))
+        return RR(maxima.eval("bessel_j(%s,%s)"%(float(nu),float(z))))
 
 def bessel_K(nu,z,prec=53):
@@ -513,7 +500,7 @@
     EXAMPLES:
         sage: bessel_K(1,1)
-        0.601907230197235
+        0.60190723019723458
         sage: bessel_K(1,1,500)
-        0.601907230197234574737540001535617339261586889968106456017767959168553582946237840168863706958258215354644099783140050908469292813493294605655726961996
+        0.60190723019723457473754000153561733926158688996810645601776795916855358294623784016886370695825821535464409978314005090846929281349329460565572696199608
     """
     from sage.libs.pari.all import pari
@@ -564,7 +551,7 @@
     EXAMPLES:
         sage: hypergeometric_U(1,1,1)
-        0.596347362323194
+        0.59634736232319407
         sage: hypergeometric_U(1,1,1,70)
-        0.59634736232319407434
+        0.59634736232319407434152
     """
     from sage.libs.pari.all import pari
@@ -574,23 +561,59 @@
     return b
 
-def spherical_bessel_J(n, var):
+def incomplete_gamma(s,x,prec=53):
+    r"""
+    Implements the incomplete Gamma function.
+
+    INPUT:
+        s, x -- ocmplex numbers.
+        prec -- bits of precision.
+
+    The argument x and s are complex numbers
+    (x must be a positive real number if s = 0).
+    The result returned is $\int_x^\infty e^{-t}t^{s-1}dt$.
+
+    EXAMPLES:
+        sage: incomplete_gamma(0.1,6,200)
+        119.99999984701215693242493354706493878953914933130704861011488
+        sage: incomplete_gamma(0,6,200)
+        120.00000000000000000000000000000000000000000000000000000000000
+        sage: incomplete_gamma(0.3,6,200)
+        119.99990598341125737887779259683594390225182610507857843438320
+        sage: incomplete_gamma(0.3,6)
+        119.99990598341125
+        sage: incomplete_gamma(0.5,6)
+        119.99830020752132
+        sage: incomplete_gamma(0.5,6,100)
+        119.99830020752131890111421425093
+    """
+    from sage.libs.pari.all import pari
+    R,a = _setup(prec)
+    b = R(pari(x).incgam(s))
+    pari.set_real_precision(a)
+    return b
+
+def spherical_bessel_J(n,x):
     r"""
     Returns the spherical Bessel function of the first kind
     for integers n > -1.
-    
     Reference: A&S 10.1.8 page 437 and A&S 10.1.15 page 439.
 
     EXAMPLES:
+        sage: x = PolynomialRing(QQ, 'x').gen()
         sage: spherical_bessel_J(2,x)
-        ((-(1 - (24/(8*x^2))))*sin(x) - (3*cos(x)/x))/x
+        '( - (1 - 24/(8*x^2))*sin(x) - 3*cos(x)/x)/x'
+
+    Here I = sqrt(-1).
+    
     """
     _init()
-    return meval("spherical_bessel_j(%s,%s)"%(ZZ(n),var))
-
-def spherical_bessel_Y(n,var):
+    R = x.parent()
+    y = R.gen()
+    return maxima.eval("spherical_bessel_j(%s,%s)"%(n,y)).replace("%i","I")
+
+def spherical_bessel_Y(n,x):
     r"""
     Returns the spherical Bessel function of the second kind
     for integers n > -1.
-    
     Reference: A&S 10.1.9 page 437 and A&S 10.1.15 page 439.
 
@@ -598,10 +621,15 @@
         sage: x = PolynomialRing(QQ, 'x').gen()
         sage: spherical_bessel_Y(2,x)
-        (-(3*sin(x)/x - (1 - (24/(8*x^2)))*cos(x)))/x
+        '-(3*sin(x)/x - (1 - 24/(8*x^2))*cos(x))/x'
+
+    Here I = sqrt(-1).
+    
     """
     _init()
-    return meval("spherical_bessel_y(%s,%s)"%(ZZ(n),var))
-
-def spherical_hankel1(n,var):
+    R = x.parent()
+    y = R.gen()
+    return maxima.eval("spherical_bessel_y(%s,%s)"%(n,y)).replace("%i","I")
+
+def spherical_hankel1(n,x):
     r"""
     Returns the spherical Hankel function of the first
@@ -611,8 +639,12 @@
     EXAMPLES:
         sage: spherical_hankel1(2,'x')
-        -3*I*(-x^2/3 - I*x + 1)*e^(I*x)/x^3
+        '-3*I*( - x^2/3 - I*x + 1)*%e^(I*x)/x^3'
+
+    Here I = sqrt(-1).
+    
     """
     _init()
-    return meval("spherical_hankel1(%s,%s)"%(ZZ(n),var))
+    y = str(x)
+    return maxima.eval("spherical_hankel1(%s,%s)"%(n,y)).replace("%i","I")
 
 def spherical_hankel2(n,x):
@@ -624,5 +656,5 @@
     EXAMPLES:
         sage: spherical_hankel2(2,'x')
-        '3*I*(-x^2/3+I*x+1)*%e^-(I*x)/x^3'
+        '3*I*( - x^2/3 + I*x + 1)*%e^-(I*x)/x^3'
 
     Here I = sqrt(-1).
@@ -640,11 +672,30 @@
 
     EXAMPLES:
+        sage: x = PolynomialRing(QQ, 'x').gen()
+        sage: y = PolynomialRing(QQ, 'y').gen()
         sage: spherical_harmonic(3,2,x,y)
-        15*sqrt(7)*cos(x)*sin(x)^2*e^(2*I*y)/(4*sqrt(30)*sqrt(pi))
+        '15*sqrt(7)*cos(x)*sin(x)^2*e^(2*I*y)/(4*sqrt(30)*sqrt(pi))'
         sage: spherical_harmonic(3,2,1,2)
-        15*sqrt(7)*e^(4*I)*cos(1)*sin(1)^2/(4*sqrt(30)*sqrt(pi))
+        -0.25556469795208248 - 0.29589824630616246*I
+
+    Here I = sqrt(-1).
+    
     """
     _init()
-    return meval("spherical_harmonic(%s,%s,%s,%s)"%(ZZ(m),ZZ(n),x,y))
+    if not(is_Polynomial(x) and is_Polynomial(y)):
+        s1 = maxima.eval("spherical_harmonic(%s,%s,%s,%s)"%(m,n,x,y))
+        s2 = s1.replace("%i","I")
+        s3 = s2.replace("%pi","pi")
+        s4 = s3.replace("%e","CC(e)")
+        return sage_eval(s4)
+    R = x.parent()
+    x1 = R.gen()
+    R = y.parent()
+    y1 = R.gen()
+    s1 = maxima.eval("spherical_harmonic(%s,%s,%s,%s)"%(m,n,x,y))
+    s2 = s1.replace("%i","I")
+    s3 = s2.replace("%pi","pi")
+    s4 = s3.replace("%e","e")
+    return s4
 
 ####### elliptic functions and integrals 
@@ -659,19 +710,18 @@
     EXAMPLES:
         sage: jacobi("sn",1,1)
-        tanh(1)
+        0.76159415595576485
         sage: jacobi("cd",1,1/2)
-        jacobi_cd(1, 1/2)
-        sage: RDF(jacobi("cd",1,1/2))
-        0.724009721659
-        sage: RDF(jacobi("cn",1,1/2)); RDF(jacobi("dn",1,1/2)); RDF(jacobi("cn",1,1/2)/jacobi("dn",1,1/2))
-        0.595976567672
-        0.823161001632
-        0.724009721659
-        sage: jsn = jacobi("sn",x,1)
-        sage: P = plot(jsn,0,1)
-        sage.: P.show()
-    """
-    _init()
-    return meval("jacobi_%s(%s,%s)"%(sym, x, m))
+        0.72400972165937116
+        sage: jacobi("cn",1,1/2);jacobi("dn",1,1/2);jacobi("cn",1,1/2)/jacobi("dn",1,1/2)
+        0.59597656767214113
+        0.82316100163159622
+        0.72400972165937116
+        sage: jsn = lambda x: jacobi("sn",x,1)
+        sage: P= plot(jsn,0,1)
+
+    Now to view this, just type show(P).
+    
+    """
+    return eval(maxima.eval("jacobi_%s(%s,%s)"%(sym, float(x), float(m))))
 
 def inverse_jacobi(sym,x,m):
@@ -683,17 +733,15 @@
     EXAMPLES:
         sage: jacobi("sn",1/2,1/2)
-        jacobi_sn(1/2, 1/2)
-        sage: float(jacobi("sn",1/2,1/2))
         0.4707504736556572
-        sage: float(inverse_jacobi("sn",0.47,1/2))
+        sage: inverse_jacobi("sn",0.47,1/2)
         0.4990982313222197
-        sage: float(inverse_jacobi("sn",0.4707504,0.5))
+        sage: inverse_jacobi("sn",0.4707504,1/2)
         0.49999991146655459
-        sage: P = plot(inverse_jacobi('sn', x, 0.5), 0, 1, plot_points=20)
+        sage: ijsn = lambda x: inverse_jacobi("sn",x,1/2)
+        sage: P= plot(ijsn,0,1)
 
     Now to view this, just type show(P).
     """
-    _init()
-    return meval("inverse_jacobi_%s(%s,%s)"%(sym, x,m))
+    return eval(maxima.eval("inverse_jacobi_%s(%s,%s)"%(sym, float(x),float(m))))
 
 #### elliptic integrals
@@ -702,35 +750,39 @@
 #### of Jacobi elliptic functions but faster to evaluate directly)
 
-## def sinh(t):
-##     try:
-##         return t.sinh()
-##     except AttributeError:
-##         from sage.calculus.calculus import exp
-##         return (exp(t)-exp(-t))/2
-
-## def cosh(t):
-##     try:
-##         return t.cosh()
-##     except AttributeError:
-##         from sage.calculus.calculus import exp        
-##         return (exp(t)+exp(-t))/2
-
-## def coth(t):
-##     try:
-##         return t.coth()
-##     except AttributeError:
-##         return 1/tanh(t)
-
-## def sech(t):
-##     try:
-##         return t.sech()
-##     except AttributeError:
-##         return 1/cosh(t)
-
-## def csch(t):
-##     try:
-##         return t.csch()
-##     except AttributeError:
-##         return 1/sinh(t)
+def sinh(t):
+    try:
+        return t.sinh()
+    except AttributeError:
+        return (exp(t)-exp(-t))/2
+
+def cosh(t):
+    try:
+        return t.cosh()
+    except AttributeError:
+        return (exp(t)+exp(-t))/2
+
+def tanh(t):
+    try:
+        return t.tanh()
+    except AttributeError:
+        return sinh(t)/cosh(t)
+
+def coth(t):
+    try:
+        return t.coth()
+    except AttributeError:
+        return 1/tanh(t)
+
+def sech(t):
+    try:
+        return t.sech()
+    except AttributeError:
+        return 1/cosh(t)
+
+def csch(t):
+    try:
+        return t.csch()
+    except AttributeError:
+        return 1/sinh(t)
 
 def dilog(t):
Index: sage/functions/transcendental.py
===================================================================
--- sage/functions/transcendental.py	(revision 4055)
+++ sage/functions/transcendental.py	(revision 3301)
@@ -148,11 +148,16 @@
         sage: zeta(RR(2))
         1.6449340668482264364724151666460251892189499012067984377356
-        sage: zeta(I)
-        0.00330022368532410 - 0.418155449141322*I
     """
     try:
         return s.zeta()
     except AttributeError:
-        return ComplexField()(s).zeta()
+        return RealField()(s).zeta()
+
+##     prec = s.prec()
+##     s = pari.new_with_prec(s, prec)
+##     z = s.zeta()._sage_()
+##     if z.prec() < prec:
+##         raise RuntimeError, "Error computing zeta(%s) -- precision loss."%s
+##     return z
 
 def zeta_symmetric(s):
Index: sage/geometry/lattice_polytope.py
===================================================================
--- sage/geometry/lattice_polytope.py	(revision 4061)
+++ sage/geometry/lattice_polytope.py	(revision 2915)
@@ -1098,5 +1098,5 @@
         Return a string representation of this face.
         """
-        return repr(self._vertices)
+        return str(self._vertices)
 
     def boundary_points(self):
Index: sage/graphs/graph.py
===================================================================
--- sage/graphs/graph.py	(revision 4065)
+++ sage/graphs/graph.py	(revision 3592)
@@ -57,5 +57,5 @@
                 sage: d = {0: [1,4,5], 1: [2,6], 2: [3,7], 3: [4,8], 4: [9], 5: [7, 8], 6: [8,9], 7: [9]}
                 sage: G = Graph(d); G
-                Graph on 10 vertices
+                A graph on 10 vertices
                 sage: G.save('sage.png')
                 
@@ -71,5 +71,5 @@
                 sage: s = ':I`AKGsaOs`cI]Gb~'
                 sage: G = Graph(s); G
-                Looped multi-graph on 10 vertices
+                A looped multi-graph on 10 vertices
                 sage: G.save('sage.png')
                 
@@ -90,5 +90,5 @@
                 [0 0 0 0 1 0 1 1 0 0]
                 sage: G = Graph(M); G
-                Graph on 10 vertices
+                A graph on 10 vertices
                 sage: G.save('sage.png')
                 
@@ -109,5 +109,5 @@
                 [ 0  0  0  0  0  0  1 -1  0  0  0  0  0  0  1]
                 sage: G = Graph(M); G
-                Graph on 10 vertices
+                A graph on 10 vertices
                 sage: G.save('sage.png')
         
@@ -165,5 +165,5 @@
             sage: d = {0 : graphs.DodecahedralGraph(), 1 : graphs.FlowerSnark(),2 : graphs.MoebiusKantorGraph(), 3 : graphs.PetersenGraph() }
             sage: d[2]
-            Moebius-Kantor Graph: Graph on 16 vertices
+            Moebius-Kantor Graph: A graph on 16 vertices
             sage: T = graphs.TetrahedralGraph()
             sage: T.vertices()
@@ -171,5 +171,5 @@
             sage: T.associate(d)
             sage: T.obj(1)
-            Flower Snark: Graph on 20 vertices
+            Flower Snark: A graph on 20 vertices
         
         4. Database
@@ -287,5 +287,5 @@
         EXAMPLES:
             sage: g = Graph({0:[1,2,3], 2:[5]}); g
-            Graph on 5 vertices
+            A graph on 5 vertices
             sage: 2 in g
             True
@@ -321,6 +321,5 @@
         if name != "No Name" and (not name is None):
             return self._nxg.name
-        else:
-            return repr(self)
+        else: return repr(self)
 
     def _latex_(self):
@@ -387,10 +386,10 @@
             sage: d = {0: [1,4,5], 1: [2,6], 2: [3,7], 3: [4,8], 4: [9], 5: [7, 8], 6: [8,9], 7: [9]}
             sage: G = Graph(d); G
-            Graph on 10 vertices
+            A graph on 10 vertices
             sage: G.name("Petersen Graph"); G
             'Petersen Graph'
-            Petersen Graph: Graph on 10 vertices
+            Petersen Graph: A graph on 10 vertices
             sage: G.name(set_to_none=True); G
-            Graph on 10 vertices
+            A graph on 10 vertices
         """
         if not new is None:
@@ -411,14 +410,14 @@
         EXAMPLE:
             sage: G = Graph(); G
-            Graph on 0 vertices
+            A graph on 0 vertices
             sage: G.loops(True); G
             True
-            Looped graph on 0 vertices
+            A looped graph on 0 vertices
 
             sage: D = DiGraph(); D
-            Digraph on 0 vertices
+            A digraph on 0 vertices
             sage: D.loops(True); D
             True
-            Looped digraph on 0 vertices
+            A looped digraph on 0 vertices
         """
         if not new is None:
@@ -479,8 +478,8 @@
         EXAMPLES:
             sage: G = Graph(); G.add_vertex(); G
-            Graph on 1 vertex
+            A graph on 1 vertex
 
             sage: D = DiGraph(); D.add_vertex(); D
-            Digraph on 1 vertex
+            A digraph on 1 vertex
         """
         if name is None: # then find an integer to use as a key
@@ -518,5 +517,5 @@
             sage: D = DiGraph({0:[1,2,3,4,5],1:[2],2:[3],3:[4],4:[5],5:[1]})
             sage: D.delete_vertex(0); D
-            Digraph on 5 vertices
+            A digraph on 5 vertices
         """
         self._nxg.delete_node(vertex)
@@ -530,5 +529,5 @@
             sage: D = DiGraph({0:[1,2,3,4,5],1:[2],2:[3],3:[4],4:[5],5:[1]})
             sage: D.delete_vertices([1,2,3,4,5]); D
-            Digraph on 1 vertex
+            A digraph on 1 vertex
         """
         self._nxg.delete_nodes_from(vertices)
@@ -564,5 +563,5 @@
             sage: d = {0 : graphs.DodecahedralGraph(), 1 : graphs.FlowerSnark(), 2 : graphs.MoebiusKantorGraph(), 3 : graphs.PetersenGraph() }
             sage: d[2]
-            Moebius-Kantor Graph: Graph on 16 vertices
+            Moebius-Kantor Graph: A graph on 16 vertices
             sage: T = graphs.TetrahedralGraph()
             sage: T.vertices()
@@ -570,5 +569,5 @@
             sage: T.associate(d)
             sage: T.obj(1)
-            Flower Snark: Graph on 20 vertices
+            Flower Snark: A graph on 20 vertices
         """
         for v in self.vertices():
@@ -587,5 +586,5 @@
             sage: d = {0 : graphs.DodecahedralGraph(), 1 : graphs.FlowerSnark(), 2 : graphs.MoebiusKantorGraph(), 3 : graphs.PetersenGraph() }
             sage: d[2]
-            Moebius-Kantor Graph: Graph on 16 vertices
+            Moebius-Kantor Graph: A graph on 16 vertices
             sage: T = graphs.TetrahedralGraph()
             sage: T.vertices()
@@ -593,5 +592,5 @@
             sage: T.associate(d)
             sage: T.obj(1)
-            Flower Snark: Graph on 20 vertices
+            Flower Snark: A graph on 20 vertices
         """
         return self._assoc[vertex]
@@ -649,95 +648,20 @@
         Uses a dictionary or permutation to relabel the (di)graph.
         If perm is a dictionary, each old vertex v is a key in the
-        dictionary, and its new label is d[v]. If perm is a list,
-        we think of it as a map i \mapsto perm[i] (only for graphs
-        with V = {0,1,...,n-1} ). If perm is a per mutation, the
-        permutation is simply applied to the graph, under the
-        assumption that V = {0,1,...,n-1} is the vertex set, and
+        dictionary, and its new label is d[v]. If perm is a permuta-
+        tion, the permutation is simply applied to the graph, under
+        the assumption that V = {0,1,...,n-1} is the vertex set, and
         the permutation acts on the set {1,2,...,n}, where we think
         of n = 0.
-        
-        EXAMPLES:
-            sage: G = Graph({0:[1],1:[2],2:[]})
-            sage: G.am()
-            [0 1 0]
-            [1 0 1]
-            [0 1 0]
-        
-        Relabeling using a list:
-            sage: G.relabel([0,2,1])
-            sage: G.am()
-            [0 0 1]
-            [0 0 1]
-            [1 1 0]
-        
-        Relabeling using a dictionary:
-            sage: G.relabel({0:2,2:0})
-            sage: G.am()
-            [0 1 1]
-            [1 0 0]
-            [1 0 0]
-        
-        Relabeling using a SAGE permutation:
-            sage: from sage.groups.perm_gps.permgroup import SymmetricGroup
-            sage: S = SymmetricGroup(3)
-            sage: gamma = S('(3,2)')
-            sage: G.relabel(gamma)
-            sage: G.am()
-            [0 0 1]
-            [0 0 1]
-            [1 1 0]
-        """
-        if type(perm) == list:
-            if isinstance(self, Graph):
-                oldd = self._nxg.adj
-                newd = {}
-                for v in oldd.iterkeys():
-                    oldtempd = oldd[v]
-                    newtempd = {}
-                    for w in oldtempd.iterkeys():
-                        newtempd[perm[w]] = oldtempd[w]
-                    newd[perm[v]] = newtempd
-                if inplace:
-                    self._nxg.adj = newd
-                else:
-                    G = self.copy()
-                    G._nxg.adj = newd
-                    return G
-            else: # DiGraph
-                oldsucc = self._nxg.succ
-                oldpred = self._nxg.pred
-                newsucc = {}
-                newpred = {}
-                for v in oldsucc.iterkeys():
-                    oldtempsucc = oldsucc[v]
-                    newtempsucc = {}
-                    for w in oldtempsucc.iterkeys():
-                        newtempsucc[perm[w]] = oldtempsucc[w]
-                    newsucc[perm[v]] = newtempsucc
-                for v in oldpred.iterkeys():
-                    oldtemppred = oldpred[v]
-                    newtemppred = {}
-                    for w in oldtemppred.iterkeys():
-                        newtemppred[perm[w]] = oldtemppred[w]
-                    newpred[perm[v]] = newtemppred
-                if inplace:
-                    self._nxg.adj = newsucc
-                    self._nxg.succ = self._nxg.adj
-                    self._nxg.pred = newpred
-                else:
-                    D = self.copy()
-                    D._nxg.adj = newsucc
-                    D._nxg.succ = D._nxg.adj
-                    D._nxg.pred = newpred
-                    return D
-        from sage.groups.perm_gps.permgroup_element import PermutationGroupElement
-        if type(perm) == PermutationGroupElement:
+        """
+        from sage.groups.perm_gps.permgroup import SymmetricGroup
+        S = SymmetricGroup(2)
+        if type(perm) == type(S('(1,2)')):
             n = self.order()
             dict = {}
-            llist = perm.list()
+            list = perm.list()
             for i in range(1,n):
-                dict[i] = llist[i-1]%n
+                dict[i] = list[i-1]%n
             if n > 0:
-                dict[0] = llist[n-1]%n
+                dict[0] = list[n-1]%n
             perm = dict
         if type(perm) == type({}):
@@ -900,5 +824,5 @@
             pos = None
         if pos is None:
-            pos = graph_fast.spring_layout_fast(self)
+            pos = networkx.drawing.spring_layout(self._nxg)
         else:
             for v in pos:
@@ -1029,9 +953,7 @@
                         multiple graphs, the first graph is taken)
             'adjacency_matrix' -- a square SAGE matrix M, with M[i][j] equal to the number
-                        of edges \{i,j\}
-            'labeled_adjacency_matrix' -- a square SAGE matrix M, with M[i][j] equal to the
-                        label of the single edge \{i,j\}
+                                  of edges \{i,j\}
             'incidence_matrix' -- a SAGE matrix, with one column C for each edge, where
-                        if C represents \{i, j\}, C[i] is -1 and C[j] is 1
+                                  if C represents \{i, j\}, C[i] is -1 and C[j] is 1
         boundary -- a list of boundary vertices, if none, graph is considered as a 'graph
                     without boundary'
@@ -1045,9 +967,9 @@
         sage: g = networkx.Graph({0:[1,2,3], 2:[5]})
         sage: Graph(g)
-        Graph on 5 vertices
+        A graph on 5 vertices
 
     2. A dictionary of dictionaries:
         sage: g = Graph({0:{1:'x',2:'z',3:'a'}, 2:{5:'out'}}); g
-        Graph on 5 vertices
+        A graph on 5 vertices
 
     The labels ('x', 'z', 'a', 'out') are labels for edges. For example, 'out' is
@@ -1057,5 +979,5 @@
     3. A dictionary of lists:
         sage: g = Graph({0:[1,2,3], 2:[5]}); g
-        Graph on 5 vertices
+        A graph on 5 vertices
 
     4. A numpy matrix or ndarray:
@@ -1063,5 +985,5 @@
         sage: A = numpy.array([[0,1,1],[1,0,1],[1,1,0]])
         sage: Graph(A)
-        Graph on 3 vertices
+        A graph on 3 vertices
     
     5. A graph6 or sparse6 string:
@@ -1070,5 +992,5 @@
         sage: s = ':I`AKGsaOs`cI]Gb~'
         sage: Graph(s)
-        Looped multi-graph on 10 vertices
+        A looped multi-graph on 10 vertices
     
     There are also list functions to take care of lists of graphs:
@@ -1076,5 +998,5 @@
         sage: s = ':IgMoqoCUOqeb\n:I`AKGsaOs`cI]Gb~\n:I`EDOAEQ?PccSsge\N\n'
         sage: graphs_list.from_sparse6(s)
-        [Looped multi-graph on 10 vertices, Looped multi-graph on 10 vertices, Looped multi-graph on 10 vertices]
+        [A looped multi-graph on 10 vertices, A looped multi-graph on 10 vertices, A looped multi-graph on 10 vertices]
     
     6. A SAGE matrix:
@@ -1096,5 +1018,5 @@
         [0 0 0 0 1 0 1 1 0 0]
         sage: Graph(M)
-        Graph on 10 vertices
+        A graph on 10 vertices
         
         B. an incidence matrix:
@@ -1108,5 +1030,5 @@
         [ 0  0  0  0  0]
         sage: Graph(M)
-        Graph on 6 vertices
+        A graph on 6 vertices
     """
     def __init__(self, data=None, pos=None, loops=False, format=None, boundary=None, **kwds):
@@ -1160,5 +1082,5 @@
             self._nxg = networkx.XGraph(d)
         elif format == 'sparse6':
-            from math import ceil, floor
+            from sage.rings.arith import ceil, floor
             from sage.misc.functional import log
             n = data.find('\n')
@@ -1167,5 +1089,5 @@
             s = data[:n]
             n, s = graph_fast.N_inverse(s[1:])
-            k = int(ceil(log(n,2)))
+            k = ceil(log(n,2))
             l = [graph_fast.binary(ord(i)-63) for i in s]
             for i in range(len(l)):
@@ -1174,5 +1096,5 @@
             b = []
             x = []
-            for i in range(int(floor(len(bits)/(k+1)))):
+            for i in range(floor(len(bits)/(k+1))):
                 b.append(int(bits[(k+1)*i:(k+1)*i+1],2))
                 x.append(int(bits[(k+1)*i+1:(k+1)*i+k+1],2))
@@ -1217,16 +1139,4 @@
                     e.append((i,j))
             self._nxg.add_edges_from(e)
-        elif format == 'weighted_adjacency_matrix':
-            d = {}
-            for i in range(data.nrows()):
-                d[i] = {}
-            self._nxg = networkx.XGraph(d, selfloops = loops, **kwds)
-            e = []
-            for i,j in data.nonzero_positions():
-                if i < j:
-                    e.append((i,j,data[i][j]))
-                elif i == j and loops:
-                    e.append((i,j,data[i][j]))
-            self._nxg.add_edges_from(e)
         elif format == 'incidence_matrix':
             b = True
@@ -1257,5 +1167,10 @@
 
     def _repr_(self):
-        name = ""
+        if not self._nxg.name is None and not self._nxg.name == "":
+            name = self._nxg.name
+            name = name + ": "
+        else:
+            name = ""
+        name += "A "
         if self.loops():
             name += "looped "
@@ -1267,7 +1182,4 @@
         else:
             name += "ices"
-        name = name.capitalize()
-        if not self._nxg.name is None and not self._nxg.name == "":
-            name = self._nxg.name + ": " + name
         return name
 
@@ -1286,5 +1198,5 @@
         EXAMPLE:
             sage: graphs.PetersenGraph().to_directed()
-            Digraph on 10 vertices
+            A digraph on 10 vertices
         """
         return DiGraph(self._nxg.to_directed(), pos=self._pos)
@@ -1296,5 +1208,5 @@
         EXAMPLE:
             sage: graphs.PetersenGraph().to_undirected()
-            Petersen graph: Graph on 10 vertices
+            Petersen graph: A graph on 10 vertices
         """
         return self.copy()
@@ -1317,8 +1229,8 @@
         EXAMPLE:
             sage: G = Graph(multiedges=True); G
-            Multi-graph on 0 vertices
+            A multi-graph on 0 vertices
             sage: G.multiple_edges(False); G
             False
-            Graph on 0 vertices
+            A graph on 0 vertices
         """
         if not new is None:
@@ -1389,5 +1301,5 @@
             sage: H = Graph()
             sage: H.add_edges( G.edge_iterator() ); H
-            Graph on 20 vertices
+            A graph on 20 vertices
         """
         self._nxg.add_edges_from( edges )
@@ -1910,7 +1822,7 @@
 
             # encode bit vector
-            from math import ceil
+            from sage.rings.arith import ceil
             from sage.misc.functional import log
-            k = int(ceil(log(n,2)))
+            k = ceil(log(n,2))
             v = 0
             i = 0
@@ -2003,11 +1915,11 @@
             sage: G = graphs.CompleteGraph(9)
             sage: H = G.subgraph([0,1,2]); H
-            Graph on 3 vertices
+            A graph on 3 vertices
             sage: G
-            Complete graph: Graph on 9 vertices
+            Complete graph: A graph on 9 vertices
             sage: K = G.subgraph([0,1,2], inplace=True); K
-            Subgraph of (Complete graph): Graph on 3 vertices
+            Subgraph of (Complete graph): A graph on 3 vertices
             sage: G
-            Subgraph of (Complete graph): Graph on 3 vertices
+            Subgraph of (Complete graph): A graph on 3 vertices
             sage: G is K
             True
@@ -2197,5 +2109,5 @@
             raise NotImplementedError, "Search algorithm does not support multiple edges yet."
         else:
-            from sage.graphs.graph_isom import search_tree, perm_group_elt
+            from sage.graphs.graph_isom import search_tree
             from sage.groups.perm_gps.permgroup import PermutationGroup
             if partition is None:
@@ -2205,5 +2117,5 @@
             else:
                 a = search_tree(self, partition, dict=False, lab=False, dig=self.loops())
-            a = PermutationGroup([perm_group_elt(aa) for aa in a])
+            a = PermutationGroup(a)
             if translation:
                 return a,b
@@ -2273,7 +2185,7 @@
             sage: D = graphs.DodecahedralGraph()
             sage: E = D.canonical_label(); E
-            Dodecahedron: Graph on 20 vertices
+            Dodecahedron: A graph on 20 vertices
             sage: D.canonical_label(proof=True)
-            (Dodecahedron: Graph on 20 vertices, {0: 0, 1: 19, 2: 16, 3: 15, 4: 9, 5: 1, 6: 10, 7: 8, 8: 14, 9: 12, 10: 17, 11: 11, 12: 5, 13: 6, 14: 2, 15: 4, 16: 3, 17: 7, 18: 13, 19: 18})
+            (Dodecahedron: A graph on 20 vertices, {0: 0, 1: 19, 2: 16, 3: 15, 4: 9, 5: 1, 6: 10, 7: 8, 8: 14, 9: 12, 10: 17, 11: 11, 12: 5, 13: 6, 14: 2, 15: 4, 16: 3, 17: 7, 18: 13, 19: 18})
             sage: D.is_isomorphic(E)
             True
@@ -2330,9 +2242,9 @@
         sage: g = networkx.DiGraph({0:[1,2,3], 2:[5]})
         sage: DiGraph(g)
-        Digraph on 5 vertices
+        A digraph on 5 vertices
     
     2. A dictionary of dictionaries:
         sage: g = DiGraph({0:{1:'x',2:'z',3:'a'}, 2:{5:'out'}}); g
-        Digraph on 5 vertices
+        A digraph on 5 vertices
 
     The labels ('x', 'z', 'a', 'out') are labels for arcs. For example, 'out' is
@@ -2342,5 +2254,5 @@
     3. A dictionary of lists:
         sage: g = DiGraph({0:[1,2,3], 2:[5]}); g
-        Digraph on 5 vertices
+        A digraph on 5 vertices
 
     4. A numpy matrix or ndarray:
@@ -2348,5 +2260,5 @@
         sage: A = numpy.array([[0,1,0],[1,0,0],[1,1,0]])
         sage: DiGraph(A)
-        Digraph on 3 vertices
+        A digraph on 3 vertices
 
     5. A SAGE matrix:
@@ -2363,5 +2275,5 @@
         [0 0 0 0 0]
         sage: DiGraph(M)
-        Digraph on 5 vertices
+        A digraph on 5 vertices
         
         B. an incidence matrix:
@@ -2375,5 +2287,5 @@
         [ 0  0  0  0  0]
         sage: DiGraph(M)
-        Digraph on 6 vertices
+        A digraph on 6 vertices
     """
 
@@ -2411,16 +2323,4 @@
                     e.append((i,j))
             self._nxg.add_edges_from(e)
-        elif format == 'weighted_adjacency_matrix':
-            d = {}
-            for i in range(data.nrows()):
-                d[i] = {}
-            self._nxg = networkx.XDiGraph(d, selfloops = loops, **kwds)
-            e = []
-            for i,j in data.nonzero_positions():
-                if i != j:
-                    e.append((i,j,data[i][j]))
-                elif i == j and loops:
-                    e.append((i,j,data[i][j]))
-            self._nxg.add_edges_from(e)
         elif format == 'incidence_matrix':
             b = True
@@ -2454,5 +2354,10 @@
 
     def _repr_(self):
-        name = ""
+        if not self._nxg.name is None and not self._nxg.name == "":
+            name = self._nxg.name
+            name = name + ": "
+        else:
+            name = ""
+        name += "A "
         if self.loops():
             name += "looped "
@@ -2464,7 +2369,4 @@
         else:
             name += "ices"
-        name = name.capitalize()
-        if not self._nxg.name is None and not self._nxg.name == "":
-            name = self._nxg.name + ": " + name
         return name
 
@@ -2482,5 +2384,5 @@
         EXAMPLE:
             sage: DiGraph({0:[1,2,3],4:[5,1]}).to_directed()
-            Digraph on 6 vertices
+            A digraph on 6 vertices
         """
         return self.copy()
@@ -2517,8 +2419,8 @@
         EXAMPLE:
             sage: D = DiGraph(multiedges=True); D
-            Multi-digraph on 0 vertices
+            A multi-digraph on 0 vertices
             sage: D.multiple_arcs(False); D
             False
-            Digraph on 0 vertices
+            A digraph on 0 vertices
         """
         if not new is None:
@@ -2599,5 +2501,5 @@
             sage: H = DiGraph()
             sage: H.add_arcs( G.arc_iterator() ); H
-            Digraph on 20 vertices
+            A digraph on 20 vertices
         """
         self._nxg.add_edges_from( arcs )
@@ -3229,11 +3131,11 @@
             sage: D = graphs.CompleteGraph(9).to_directed()
             sage: H = D.subgraph([0,1,2]); H
-            Digraph on 3 vertices
+            A digraph on 3 vertices
             sage: D
-            Digraph on 9 vertices
+            A digraph on 9 vertices
             sage: K = D.subgraph([0,1,2], inplace=True); K
-            Subgraph of (None): Digraph on 3 vertices
+            Subgraph of (None): A digraph on 3 vertices
             sage: D
-            Subgraph of (None): Digraph on 3 vertices
+            Subgraph of (None): A digraph on 3 vertices
             sage: D is K
             True
@@ -3343,5 +3245,5 @@
             raise NotImplementedError, "Search algorithm does not support multiple edges yet."
         else:
-            from sage.graphs.graph_isom import search_tree, perm_group_elt
+            from sage.graphs.graph_isom import search_tree
             from sage.groups.perm_gps.permgroup import PermutationGroup
             if partition is None:
@@ -3351,5 +3253,5 @@
             else:
                 a = search_tree(self, partition, dict=False, lab=False, dig=True)
-            a = PermutationGroup([perm_group_elt(aa) for aa in a])
+            a = PermutationGroup(a)
             if translation:
                 return a,b
@@ -3374,12 +3276,12 @@
             b,a = self.canonical_label(proof=True)
             d,c = other.canonical_label(proof=True)
+            map = {}
+            cc = c.items()
+            for vert in self.vertices():
+                for aa,bb in cc:
+                    if bb == a[vert]:
+                        map[vert] = aa
+                        break
             if enum(b) == enum(d):
-                map = {}
-                cc = c.items()
-                for vert in self.vertices():
-                    for aa,bb in cc:
-                        if bb == a[vert]:
-                            map[vert] = aa
-                            break
                 return True, map
             else:
@@ -3420,5 +3322,5 @@
     spring = False
     if pos3d is None:
-        pos3d = graph_fast.spring_layout_fast(g, dim=3)
+        pos3d = networkx.spring_layout(g._nxg, dim=3)
     try:
         for v in verts:
@@ -3454,29 +3356,13 @@
     """
     Used for isomorphism checking.
-    
-    EXAMPLES:
-        sage: from sage.graphs.graph import enum
-        sage: enum(graphs.DodecahedralGraph())
-        646827340296833569479885332381965103655612500627043016896502674924517797573929148319427466126170568392555309533861838850L
-        sage: enum(graphs.MoebiusKantorGraph())
-        29627597595494233374689380190219099810725571659745484382284031717525232288040L
-        sage: enum(graphs.FlowerSnark())
-        645682215283153372602620320081348424178216159521280462146968720908564261127120716040952785862033320307812724373694972050L
-        sage: enum(graphs.CubeGraph(3))
-        6100215452666565930L              # 32-bit
-        6100215452666565930               # 64-bit
-        sage: enum(graphs.CubeGraph(4))
-        31323620658472264895128471376615338141839885567113523525061169966087480352810L
-        sage: enum(graphs.CubeGraph(5))
-        56178607138625465573345383656463935701397275938329921399526324254684498525419117323217491887221387354861371989089284563861938014744765036177184164647909535771592043875566488828479926184925998575521710064024379281086266290501476331004707336065735087197243607743454550839234461575558930808225081956823877550090L
-        sage: enum(graphs.CubeGraph(6))
-        17009933328531023098235951265708015080189260525466600242007791872273951170067729430659625711869482140011822425402311004663919203785115296476561677814427201708237805402966561863692388687547518491537427897858240566495945005294876576523289206747123399572439707189803821880345487300688962557172856432472391025950779306221469432919735886988596366979797317084123956762362685536557279604675024249987913439836592296340787741671304722135394212035449285260308821361913500205796919484488876249630521666898413890977354122918711285458724686283296097840711521153201188450783978019001984591992381570913097193343212274205747843852376395748070926193308573472616983062165141386183945049871456376379041631456999916186868438148001405477879591035696239287238767746380404501285533026300096772164676955425088646172718295360584249310479706751274583871684827338312536787740914529353458829503642591918761588296961192261166874864565050490306157300749101788751129640698534818737753110920871293122429238702542726347017441416450649382146313791818349648006634724962025571237208317435310419071153813687071275479812184286929976456778629116002591936357623320676067640749567446551071011889378108453641887998273235139859889734259803684619153716302058849155208478850L
     """
+    from sage.rings.integer import Integer
     M = graph.am()
-    enumeration = 0
-    n = graph.order()
-    for i, j in M.nonzero_positions():
-        enumeration += 1 << ((n-(i+1))*n + n-(j+1))
-    return enumeration
-
-
+    string = ''
+    for r in M.rows():
+        for c in r:
+            string += str(c)
+    if string=='': string='0'
+    return Integer(string,2)
+
+
Index: sage/graphs/graph_database.py
===================================================================
--- sage/graphs/graph_database.py	(revision 3734)
+++ sage/graphs/graph_database.py	(revision 3586)
@@ -161,5 +161,5 @@
             # Inspect and display graphs individually:
             sage: glist[0]
-            Graph on 5 vertices
+            A graph on 5 vertices
             sage.: glist[8].show(layout='circular')
             
Index: sage/graphs/graph_fast.pyx
===================================================================
--- sage/graphs/graph_fast.pyx	(revision 3744)
+++ sage/graphs/graph_fast.pyx	(revision 3154)
@@ -2,12 +2,10 @@
 Graph Theory SageX functions
 
-AUTHORS:
-    -- Robert L. Miller   (2007-02-13): initial version
-    -- Robert W. Bradshaw (2007-03-31): fast spring layout algorithms
+AUTHOR:
+    -- Robert L. Miller (2007-02-13): initial version
 """
 
 #*****************************************************************************
 #           Copyright (C) 2007 Robert L. Miller <rlmillster@gmail.com>
-#                         2007 Robert W. Bradshaw <robertwb@math.washington.edu>
 #
 # Distributed  under  the  terms  of  the  GNU  General  Public  License (GPL)
@@ -15,220 +13,5 @@
 #*****************************************************************************
 
-include "../ext/interrupt.pxi"
-include '../ext/cdefs.pxi'            
-include '../ext/stdsage.pxi'
-from random import random
-
-cdef extern from *:
-    double sqrt(double)
-
-def spring_layout_fast_split(G, iterations=50, dim=2, vpos=None):
-    """
-    Graphs each component of G separately, placing them adjacent to 
-    each other. This is done because on a disconnected graph, the 
-    spring layout will push components further and further from each
-    other without bound, resulting in very tight clumps for each
-    component. 
-    
-    NOTE: 
-        If the axis are scaled to fit the plot in a square, the 
-        horizontal distance may end up being "squished" due to 
-        the several adjacent components. 
-    
-    EXAMPLE:
-        sage: G = graphs.DodecahedralGraph()
-        sage: for i in range(10): G.add_cycle(range(100*i, 100*i+3))
-        sage: N = G.plot()
-        
-    AUTHOR:
-        Robert Bradshaw
-    """
-    Gs = G.connected_components_subgraphs()
-    pos = {}
-    left = 0
-    buffer = 1/sqrt(len(G))
-    for g in Gs:
-        cur_pos = spring_layout_fast(g, iterations, dim, vpos)
-        xmin = min([x[0] for x in cur_pos.values()])
-        xmax = max([x[0] for x in cur_pos.values()])
-        if len(g) > 1:
-            buffer = (xmax - xmin)/sqrt(len(g))
-        for v, loc in cur_pos.iteritems():
-            loc[0] += left - xmin + buffer
-            pos[v] = loc
-        left += xmax - xmin + buffer
-    return pos
-
-def spring_layout_fast(G, iterations=50, dim=2, vpos=None):
-    """
-    Spring force model layout
-    
-    This function primarily acts as a wrapper around run_spring, 
-    converting to and from raw c types. 
-    
-    This kind of speed cannot be achieved by naive pyrexification of the 
-    function alone, especially if we require a function call (let alone
-    an object creation) every time we want to add a pair of doubles. 
-    """
-
-    G = G.networkx_graph()
-    vlist = list(G) # this defines a consistant order
-    
-    cdef int i, j, x
-    cdef int n = G.order()
-    if n == 0:
-        return {}
-    
-    cdef double* pos = <double*>sage_malloc(n * dim * sizeof(double))
-    if pos is NULL:
-            raise MemoryError, "error allocating scratch space for spring layout"
-
-    # convert or create the starting positions as a flat list of doubles
-    if vpos is None:  # set the initial positions randomly in 1x1 box
-        for i from 0 <= i < n*dim:
-            pos[i] = random()
-    else:
-        for i from 0 <= i < n:
-            loc = vpos[vlist[i]]
-            for x from 0 <= x <dim:
-                pos[i*dim + x] = loc[x]
-    
-    
-    # here we construct a lexographically ordered list of all edges
-    # where elist[2*i], elist[2*i+1] represents the i-th edge
-    cdef int* elist = <int*>sage_malloc( (2 * len(G.edges()) + 2) * sizeof(int)  )
-    if elist is NULL:
-        sage_free(pos)
-        raise MemoryError, "error allocating scratch space for spring layout"
-            
-    cdef int cur_edge = 0
-    
-    for i from 0 <= i < n:
-        for j from i < j < n:
-            if G.has_edge(vlist[i], vlist[j]):
-                elist[cur_edge] = i
-                elist[cur_edge+1] = j
-                cur_edge += 2
-                
-    # finish the list with -1, -1 which never gets matched
-    # but does get compared against when looking for the "next" edge
-    elist[cur_edge] = -1
-    elist[cur_edge+1] = -1
-    
-    run_spring(iterations, dim, pos, elist, n)
-    
-    # put the data back into a position dictionary
-    vpos = {}
-    for i from 0 <= i < n:
-        vpos[vlist[i]] = [pos[i*dim+x] for x from 0 <= x < dim]
-
-    sage_free(pos)
-    sage_free(elist)
-    
-    return vpos
-
-
-cdef run_spring(int iterations, int dim, double* pos, int* edges, int n):
-    """
-    Find a locally optimal layout for this graph, according to the 
-    constraints that neighboring nodes want to be a fixed distance 
-    from each other, and non-neighboring nodes always repel. 
-    
-    This is not a true physical model of mutually-replusive particles 
-    with springs, rather it is more a model of such things traveling, 
-    without any inertia, through an (ever thickening) fluid. 
-    
-    TODO: The inertial model could be incorperated (with F=ma)
-    TODO: Are the hard-coded constants here optimal? 
-    
-    INPUT:
-        iterations -- number of steps to take
-        dim        -- number of dimensions of freedom
-        pos        -- already initalized initial positions
-                      Each vertext is stored as [dim] consecutive doubles.
-                      These doubles are then placed consecutively in the array. 
-                      For example, if dim=3, we would have
-                      pos = [x_1, y_1, z_1, x_2, y_2, z_2, ... , x_n, y_n, z_n]
-        edges      -- List of edges, sorted lexographically by the first 
-                      (smallest) vertex, terminated by -1, -1.
-                      The first two entries represent the first edge, and so on. 
-        n          -- number of vertices in the graph
-    
-    OUTPUT: 
-        Modifies contents of pos.
-        
-    AUTHOR: 
-        Robert Bradshaw
-    """
-
-    cdef int cur_iter, cur_edge
-    cdef int i, j, x
-    
-    cdef double t = 1, dt = t/iterations, k = sqrt(1.0/n)
-    cdef double square_dist, force, scale
-    cdef double* disp_i
-    cdef double* disp_j
-    cdef double* delta
-    
-    cdef double* disp = <double*>sage_malloc((n+1) * dim * sizeof(double))
-    if disp is NULL:
-            raise MemoryError, "error allocating scratch space for spring layout"
-    delta = &disp[n*dim]
-    
-    _sig_on
-    
-    for cur_iter from 0 <= cur_iter < iterations:
-      cur_edge = 1 # offset by one for fast checking against 2nd element first
-      # zero out the disp vectors
-      memset(disp, 0, n * dim * sizeof(double))
-      for i from 0 <= i < n:
-          disp_i = disp + (i*dim)
-          for j from i < j < n:
-              disp_j = disp + (j*dim)
-              
-              for x from 0 <= x < dim:
-                  delta[x] = pos[i*dim+x] - pos[j*dim+x]
-                  
-              square_dist = delta[0] * delta[0]
-              for x from 1 <= x < dim:
-                  square_dist += delta[x] * delta[x]
-                  
-              if square_dist < 0.01:
-                  square_dist = 0.01
-              
-              # they repel according to the (capped) inverse square law
-              force = k*k/square_dist
-              
-              # and if they are neighbors, attract according Hooke's law
-              if edges[cur_edge] == j and edges[cur_edge-1] == i:
-                  force -= sqrt(square_dist)/k
-                  cur_edge += 2
-                  
-              # add this factor into each of the involved points
-              for x from 0 <= x < dim:
-                  disp_i[x] += delta[x] * force
-                  disp_j[x] -= delta[x] * force
-
-      # now update the positions
-      for i from 0 <= i < n:
-          disp_i = disp + (i*dim)
-          
-          square_dist = disp_i[0] * disp_i[0]
-          for x from 1 <= x < dim:
-              square_dist += disp_i[x] * disp_i[x]
-          
-          scale = t / (1 if square_dist < 0.01 else sqrt(square_dist))
-              
-          for x from 0 <= x < dim:
-              pos[i*dim+x] += disp_i[x] * scale
-              
-      t -= dt
-              
-    _sig_off
-              
-    sage_free(disp)
-
-
-
+include '../ext/cdefs.pxi'
 
 def binary(n, length=None):
Index: sage/graphs/graph_generators.py
===================================================================
--- sage/graphs/graph_generators.py	(revision 3734)
+++ sage/graphs/graph_generators.py	(revision 3586)
@@ -318,5 +318,5 @@
             sage: G = graphs.ClawGraph()
             sage: G
-            Claw graph: Graph on 4 vertices
+            Claw graph: A graph on 4 vertices
         """
         pos_dict = {0:[0,1],1:[-1,0],2:[0,0],3:[1,0]}
@@ -1136,5 +1136,5 @@
             sage: F = graphs.FlowerSnark()
             sage: F
-            Flower Snark: Graph on 20 vertices
+            Flower Snark: A graph on 20 vertices
             sage: F.graph6_string()
             'ShCGHC@?GGg@?@?Gp?K??C?CA?G?_G?Cc'
@@ -1178,5 +1178,5 @@
             sage: FRUCHT = graphs.FruchtGraph()
             sage: FRUCHT
-            Frucht graph: Graph on 12 vertices
+            Frucht graph: A graph on 12 vertices
             sage: FRUCHT.graph6_string()
             'KhCKM?_EGK?L'
@@ -1220,5 +1220,5 @@
             sage: H = graphs.HeawoodGraph()
             sage: H
-            Heawood graph: Graph on 14 vertices
+            Heawood graph: A graph on 14 vertices
             sage: H.graph6_string()
             'MhEGHC@AI?_PC@_G_'
@@ -1259,5 +1259,5 @@
             sage: MK = graphs.MoebiusKantorGraph()
             sage: MK
-            Moebius-Kantor Graph: Graph on 16 vertices
+            Moebius-Kantor Graph: A graph on 16 vertices
             sage: MK.graph6_string()
             'OhCGKE?O@?ACAC@I?Q_AS'
@@ -1332,5 +1332,5 @@
             sage: T = graphs.ThomsenGraph()
             sage: T
-            Thomsen graph: Graph on 6 vertices
+            Thomsen graph: A graph on 6 vertices
             sage: T.graph6_string()
             'EFz_'
Index: sage/graphs/graph_isom.py
===================================================================
--- sage/graphs/graph_isom.py	(revision 3880)
+++ sage/graphs/graph_isom.py	(revision 3596)
@@ -31,5 +31,4 @@
 ##############################################################################
 
-from sage.graphs.graph import Graph, DiGraph
 
 def finer(Pi1, Pi2):
@@ -139,6 +138,6 @@
     return l
 
-def orbit_partition(gamma, list_perm=False):
-    r"""
+def orbit_partition(G, gamma):
+    """
     Assuming that G is a graph on vertices {0,1,...,n-1}, and gamma is an
     element of SymmetricGroup(n), returns the partition of the vertex set
@@ -147,8 +146,4 @@
     determined by a cyclic representation of gamma.
     
-    INPUT:
-        list_perm -- if True, assumes gamma is a list representing the map
-    i \mapsto gamma[i].
-
     EXAMPLES:
         sage: import sage.graphs.graph_isom
@@ -157,38 +152,20 @@
         sage: S = SymmetricGroup(10)
         sage: gamma = S('(10,1,2,3,4)(5,6,7)(8,9)')
-        sage: orbit_partition(gamma)
+        sage: orbit_partition(G,gamma)
         [[1, 2, 3, 4, 0], [5, 6, 7], [8, 9]]
         sage: gamma = S('(10,5)(1,6)(2,7)(3,8)(4,9)')
-        sage: orbit_partition(gamma)
+        sage: orbit_partition(G,gamma)
         [[1, 6], [2, 7], [3, 8], [4, 9], [5, 0]]
     """
-    if list_perm:
-        n = len(gamma)
-        seen = [1] + [0]*(n-1)
-        i = 0
-        p = 0
-        partition = [[0]]
-        while sum(seen) < n:
-            if gamma[i] != partition[p][0]:
-                partition[p].append(gamma[i])
-                i = gamma[i]
-                seen[i] = 1
-            else:
-                i = min([j for j in range(n) if seen[j] == 0])
-                partition.append([i])
-                p += 1
-                seen[i] = 1
-        return partition
-    else:
-        n = len(gamma.list())
-        l = []
-        for i in range(1,n+1):
-            orb = gamma.orbit(i)
-            if orb not in l: l.append(orb)
-        for i in l:
-            for j in range(len(i)):
-                if i[j] == n:
-                    i[j] = 0
-        return l
+    n = len(gamma.list())
+    l = []
+    for i in range(1,n+1):
+        orb = gamma.orbit(i)
+        if orb not in l: l.append(orb)
+    for i in l:
+        for j in range(len(i)):
+            if i[j] == n:
+                i[j] = 0
+    return l
 
 def sat225(Pi, n):
@@ -224,7 +201,12 @@
     """
     i = 0
-    for u in W:
-        if G._nxg.adj[u].has_key(v):
-            i += 1
+    if G.is_directed():
+        for u in W:
+            if G.has_arc(u,v):
+                i += 1
+    else:
+        for u in W:
+            if G.has_edge(u,v):
+                i += 1
     return i
 
@@ -504,13 +486,9 @@
     return prod([l for l in LL if l!=0])
 
-def get_permutation(eta, nu, list_perm=False):
-    r"""
+def get_permutation(eta, nu):
+    """
     Given two terminal nodes of the search tree, eta and nu, each last
     partition is discrete, and the order of the partition determines a
     permutation gamma such that gamma(eta) = nu. Returns the partition gamma.
-    
-    INPUT:
-        list_perm -- if True, returns a list L representing the map i \mapsto
-    L[i].
     
     EXAMPLE:
@@ -523,71 +501,46 @@
         sage: get_permutation(eta, nu)
         (1,8,7,14,15,16,17,18,19,20)(12,4,11,3,10,2,9,6,13,5)
-        sage: get_permutation(eta, nu, list_perm=True)
-        [1, 8, 9, 10, 11, 12, 13, 14, 7, 6, 2, 3, 4, 5, 15, 16, 17, 18, 19, 0]
-    """
-    a = nu[-1]
-    b = eta[-1]
+    """
+    from sage.rings.integer import Integer
+    from sage.groups.perm_gps.permgroup import SymmetricGroup
+    a = nu[len(nu)-Integer(1)]
+    b = eta[len(eta)-Integer(1)]
     n = len(b)
-    if list_perm:
-        gamma = []
-        i = 0
-        while len(gamma) < n:
-            for j in range(n):
-                if b[j][0] == i:
-                    gamma.append(a[j][0])
-                    i += 1
+    S = SymmetricGroup(n)
+    gamma = []
+    for i in range(len(b)):
+        if b[i][0] != a[i][0]:
+            gamma.append([b[i][0],a[i][0]])
+    i = 0
+    while i < len(gamma):
+        if gamma[i][0] == gamma[i][-1]:
+            i += 1
+        else:
+            for j in range(i+1,len(gamma)):
+                if gamma[i][-1] == gamma[j][0]:
+                    gamma[i] = gamma[i] + gamma[j][1:]
+                    gamma.pop(j)
                     break
-        return gamma
+    for i in range(len(gamma)):
+        gamma[i] = gamma[i][1:]
+    if len(gamma) == 0:
+        gamma = S('()')
     else:
-        from sage.groups.perm_gps.permgroup import SymmetricGroup
-        S = SymmetricGroup(n)
-        gamma = []
-        for i in range(len(b)):
-            if b[i][0] != a[i][0]:
-                gamma.append([b[i][0],a[i][0]])
-        i = 0
-        while i < len(gamma):
-            if gamma[i][0] == gamma[i][-1]:
-                i += 1
-            else:
-                for j in range(i+1,len(gamma)):
-                    if gamma[i][-1] == gamma[j][0]:
-                        gamma[i] = gamma[i] + gamma[j][1:]
-                        gamma.pop(j)
-                        break
-        for i in range(len(gamma)):
-            gamma[i] = gamma[i][1:]
-        if len(gamma) == 0:
-            gamma = S('()')
-        else:
-            gamma = S(str(gamma)[1:-1].replace('[','(').replace(']',')').\
-                   replace(' ', '').replace('(0','('+str(n)).replace(',0',','+str(n)))
-        return gamma
-
-def term_pnest_graph(G, nu, enumer=False):
+        gamma = S(str(gamma)[1:-1].replace('[','(').replace(']',')').\
+               replace(' ', '').replace('(0','('+str(n)).replace(',0',','+str(n)))
+    return gamma
+
+def term_pnest_graph(G, nu):
     """
     BDM's G(nu): returns the graph G, relabeled in the order found in
     nu[last]. Assumes nu is a terminal partition nest in T(G, Pi).
     """
-    n = G.order()
+    ord = nu[len(nu)-1]
     d = {}
-    for i in range(n):
-        d[nu[-1][i][0]] = i
-    if enumer:
-        # we know that the vertex set is {0,...,n-1}...
-        numbr = 0
-        if isinstance(G, Graph):
-            for i,j,l in G.edge_iterator():
-                numbr += 1<<((n-(d[i]+1))*n + n-(d[j]+1))
-                numbr += 1<<((n-(d[j]+1))*n + n-(d[i]+1))
-        elif isinstance(G, DiGraph):
-            for i,j,l in G.arc_iterator():
-                numbr += 1<<((n-(d[i]+1))*n + n-(d[j]+1))
-        return numbr
-    else:
-        ord = nu[-1]
-        H = G.copy()
-        H.relabel(d)
-        return H
+    for i in range(len(nu[len(nu)-1])):
+        d[nu[len(nu)-1][i][0]] = i
+    H = G.copy()
+    H.relabel(d)
+    return H
 
 def search_tree(G, Pi, lab=True, dig=False, dict=False, proof=False):
@@ -629,5 +582,5 @@
         sage: from sage.groups.perm_gps.permgroup import PermutationGroup
         sage: import sage.graphs.graph_isom
-        sage: from sage.graphs.graph_isom import search_tree, perm_group_elt
+        sage: from sage.graphs.graph_isom import search_tree
         sage: from sage.graphs.graph import enum
 
@@ -636,9 +589,9 @@
         sage: a,b = search_tree(G, Pi)
         sage: print a, enum(b)
-        [[0, 19, 3, 2, 6, 5, 4, 17, 18, 11, 10, 9, 13, 12, 16, 15, 14, 7, 8, 1], [0, 1, 8, 9, 13, 14, 7, 6, 2, 3, 19, 18, 17, 4, 5, 15, 16, 12, 11, 10], [0, 19, 18, 11, 12, 16, 17, 4, 3, 2, 1, 8, 7, 6, 5, 15, 14, 13, 9, 10], [1, 8, 9, 10, 11, 12, 13, 14, 7, 6, 2, 3, 4, 5, 15, 16, 17, 18, 19, 0]] 17318942212009113839976787462421724338461987195898671092180383421848885858584973127639899792828728124797968735273000
+        [(16,14)(13,12)(7,17)(6,4)(9,11)(8,18)(2,3)(1,19), (14,5)(17,12)(4,13)(6,7)(18,11)(3,9)(2,8)(19,10), (16,14,5)(7,4,12)(6,17,13)(8,3,11)(2,18,9)(1,19,10), (1,8,7,14,15,16,17,18,19,20)(12,4,11,3,10,2,9,6,13,5)] 17318942212009113839976787462421724338461987195898671092180383421848885858584973127639899792828728124797968735273000
         sage: c = search_tree(G, Pi, lab=False)
         sage: print c
-        [[0, 19, 3, 2, 6, 5, 4, 17, 18, 11, 10, 9, 13, 12, 16, 15, 14, 7, 8, 1], [0, 1, 8, 9, 13, 14, 7, 6, 2, 3, 19, 18, 17, 4, 5, 15, 16, 12, 11, 10], [0, 19, 18, 11, 12, 16, 17, 4, 3, 2, 1, 8, 7, 6, 5, 15, 14, 13, 9, 10], [1, 8, 9, 10, 11, 12, 13, 14, 7, 6, 2, 3, 4, 5, 15, 16, 17, 18, 19, 0]]
-        sage: DodecAut = PermutationGroup([perm_group_elt(aa) for aa in a])
+        [(16,14)(13,12)(7,17)(6,4)(9,11)(8,18)(2,3)(1,19), (14,5)(17,12)(4,13)(6,7)(18,11)(3,9)(2,8)(19,10), (16,14,5)(7,4,12)(6,17,13)(8,3,11)(2,18,9)(1,19,10), (1,8,7,14,15,16,17,18,19,20)(12,4,11,3,10,2,9,6,13,5)]
+        sage: DodecAut = PermutationGroup(a)
         sage: DodecAut.character_table()
         [                     1                      1                      1                      1                      1                      1                      1                      1                      1                      1]
@@ -652,5 +605,5 @@
         [                     5                      1                     -1                      1                      0                      0                     -1                      0                      0                      5]
         [                     5                     -1                     -1                      1                      0                      0                      1                      0                      0                     -5]
-        sage: DodecAut2 = PermutationGroup([perm_group_elt(cc) for cc in c])
+        sage: DodecAut2 = PermutationGroup(c)
         sage: DodecAut2.character_table()
         [                     1                      1                      1                      1                      1                      1                      1                      1                      1                      1]
@@ -669,7 +622,7 @@
         sage: a,b = search_tree(G, Pi)
         sage: print a, enum(b)
-        [[0, 1, 2, 7, 5, 4, 6, 3, 9, 8], [0, 1, 6, 8, 5, 4, 2, 9, 3, 7], [0, 4, 3, 8, 5, 1, 9, 2, 6, 7], [1, 0, 4, 9, 6, 2, 5, 3, 7, 8]] 8716441511243809436161868448
+        [(9,8)(3,7)(4,5), (3,8)(7,9)(6,2)(4,5), (6,9,7,2,3,8)(4,5,1), (1,10)(7,3,9,8)(4,6,5,2)] 8716441511243809436161868448
         sage: c = search_tree(G, Pi, lab=False)
-        sage: PAut = PermutationGroup([perm_group_elt(aa) for aa in a])
+        sage: PAut = PermutationGroup(a)
         sage: PAut.character_table()
         [ 1  1  1  1  1  1  1]
@@ -680,5 +633,5 @@
         [ 5 -1  1 -1 -1  1  0]
         [ 6  0 -2  0  0  0  1]
-        sage: PAut = PermutationGroup([perm_group_elt(cc) for cc in c])
+        sage: PAut = PermutationGroup(c)
         sage: PAut.character_table()
         [ 1  1  1  1  1  1  1]
@@ -699,10 +652,10 @@
         sage: a,b = search_tree(G, Pi)
         sage: print a, enum(b)
-        [[0, 3, 2, 1, 6, 5, 4, 7], [0, 1, 4, 5, 2, 3, 6, 7], [0, 3, 6, 5, 2, 1, 4, 7], [1, 0, 3, 2, 5, 4, 7, 6]] 520239721777506480
+        [(6,4)(1,3), (4,2)(3,5), (6,4,2)(1,3,5), (1,8)(6,7)(3,2)(5,4)] 520239721777506480
         sage: c = search_tree(G, Pi, lab=False)
 
-        sage: PermutationGroup([perm_group_elt(aa) for aa in a]).order()
+        sage: PermutationGroup(a).order()
         48
-        sage: PermutationGroup([perm_group_elt(cc) for cc in c]).order()
+        sage: PermutationGroup(c).order()
         48
         sage: DodecAut.order()
@@ -751,14 +704,14 @@
         []              0     []              0     []             
         []              0     []              0     []             
-        [[1, 0]]        0     [[1, 0]]        0     [[1, 0]]       
-        [[1, 0]]        0     [[1, 0]]        0     [[1, 0]]       
+        [(1,2)]         0     [(1,2)]         0     [(1,2)]        
+        [(1,2)]         0     [(1,2)]         0     [(1,2)]        
         []              6     []              6     []             
         []              6     []              6     []             
-        [[1, 0]]        6     [[1, 0]]        6     [[1, 0]]       
-        [[1, 0]]        6     [[1, 0]]        6     [[1, 0]]
-        
+        [(1,2)]         6     [(1,2)]         6     [(1,2)]        
+        [(1,2)]         6     [(1,2)]         6     [(1,2)]        
+
         sage: graph3 = all_labeled_graphs(3)
         sage: part3 = all_ordered_partitions(range(3))
-        sage: for G in graph3:               # long time (~30 secs)
+        sage: for G in graph3:               # long time
         ...    for Pi in part3:
         ...        a,b = search_tree(G, Pi)
@@ -769,30 +722,30 @@
         []              0     []              0     []             
         []              0     []              0     []             
-        [[0, 2, 1]]     0     [[0, 2, 1]]     0     [[0, 2, 1]]    
-        [[0, 2, 1]]     0     [[0, 2, 1]]     0     [[0, 2, 1]]    
+        [(2,1)]         0     [(2,1)]         0     [(2,1)]        
+        [(2,1)]         0     [(2,1)]         0     [(2,1)]        
         []              0     []              0     []             
         []              0     []              0     []             
-        [[2, 1, 0]]     0     [[2, 1, 0]]     0     [[2, 1, 0]]    
-        [[2, 1, 0]]     0     [[2, 1, 0]]     0     [[2, 1, 0]]    
+        [(2,3)]         0     [(2,3)]         0     [(2,3)]        
+        [(2,3)]         0     [(2,3)]         0     [(2,3)]        
         []              0     []              0     []             
         []              0     []              0     []             
-        [[1, 0, 2]]     0     [[1, 0, 2]]     0     [[1, 0, 2]]    
-        [[1, 0, 2]]     0     [[1, 0, 2]]     0     [[1, 0, 2]]    
-        [[1, 0, 2]]     0     [[1, 0, 2]]     0     [[1, 0, 2]]    
-        [[2, 1, 0]]     0     [[2, 1, 0]]     0     [[2, 1, 0]]    
-        [[1, 0, 2]]     0     [[1, 0, 2]]     0     [[1, 0, 2]]    
-        [[0, 2, 1]]     0     [[0, 2, 1]]     0     [[0, 2, 1]]    
-        [[2, 1, 0]]     0     [[2, 1, 0]]     0     [[2, 1, 0]]    
-        [[0, 2, 1]]     0     [[0, 2, 1]]     0     [[0, 2, 1]]    
-        [[0, 2, 1], [1, 0, 2]] 0     [[0, 2, 1], [1, 0, 2]] 0     [[0, 2, 1], [1, 0, 2]]
-        [[0, 2, 1], [1, 0, 2]] 0     [[0, 2, 1], [1, 0, 2]] 0     [[0, 2, 1], [1, 0, 2]]
-        [[0, 2, 1], [1, 0, 2]] 0     [[0, 2, 1], [1, 0, 2]] 0     [[0, 2, 1], [1, 0, 2]]
-        [[0, 2, 1], [1, 0, 2]] 0     [[0, 2, 1], [1, 0, 2]] 0     [[0, 2, 1], [1, 0, 2]]
-        [[0, 2, 1], [1, 0, 2]] 0     [[0, 2, 1], [1, 0, 2]] 0     [[0, 2, 1], [1, 0, 2]]
-        [[0, 2, 1], [1, 0, 2]] 0     [[0, 2, 1], [1, 0, 2]] 0     [[0, 2, 1], [1, 0, 2]]
-        []              10    []              10    []             
-        []              10    []              10    []             
-        [[0, 2, 1]]     10    [[0, 2, 1]]     10    [[0, 2, 1]]    
-        [[0, 2, 1]]     10    [[0, 2, 1]]     10    [[0, 2, 1]]    
+        [(1,3)]         0     [(1,3)]         0     [(1,3)]        
+        [(1,3)]         0     [(1,3)]         0     [(1,3)]        
+        [(1,3)]         0     [(1,3)]         0     [(1,3)]        
+        [(2,3)]         0     [(2,3)]         0     [(2,3)]        
+        [(1,3)]         0     [(1,3)]         0     [(1,3)]        
+        [(2,1)]         0     [(2,1)]         0     [(2,1)]        
+        [(2,3)]         0     [(2,3)]         0     [(2,3)]        
+        [(2,1)]         0     [(2,1)]         0     [(2,1)]        
+        [(2,1), (1,3)]  0     [(2,1), (1,3)]  0     [(2,1), (1,3)] 
+        [(2,1), (1,3)]  0     [(2,1), (1,3)]  0     [(2,1), (1,3)] 
+        [(2,1), (1,3)]  0     [(2,1), (1,3)]  0     [(2,1), (1,3)] 
+        [(2,1), (1,3)]  0     [(2,1), (1,3)]  0     [(2,1), (1,3)] 
+        [(2,1), (1,3)]  0     [(2,1), (1,3)]  0     [(2,1), (1,3)] 
+        [(2,1), (1,3)]  0     [(2,1), (1,3)]  0     [(2,1), (1,3)] 
+        []              10    []              10    []             
+        []              10    []              10    []             
+        [(2,1)]         10    [(2,1)]         10    [(2,1)]        
+        [(2,1)]         10    [(2,1)]         10    [(2,1)]        
         []              68    []              68    []             
         []              160   []              160   []             
@@ -806,13 +759,13 @@
         []              10    []              10    []             
         []              10    []              10    []             
-        [[0, 2, 1]]     160   [[0, 2, 1]]     160   [[0, 2, 1]]    
-        []              10    []              10    []             
-        [[0, 2, 1]]     160   [[0, 2, 1]]     160   [[0, 2, 1]]    
-        [[0, 2, 1]]     10    [[0, 2, 1]]     10    [[0, 2, 1]]    
-        [[0, 2, 1]]     10    [[0, 2, 1]]     10    [[0, 2, 1]]    
-        [[0, 2, 1]]     10    [[0, 2, 1]]     10    [[0, 2, 1]]    
-        [[0, 2, 1]]     10    [[0, 2, 1]]     10    [[0, 2, 1]]    
-        [[0, 2, 1]]     10    [[0, 2, 1]]     10    [[0, 2, 1]]    
-        [[0, 2, 1]]     10    [[0, 2, 1]]     10    [[0, 2, 1]]    
+        [(2,1)]         160   [(2,1)]         160   [(2,1)]        
+        []              10    []              10    []             
+        [(2,1)]         160   [(2,1)]         160   [(2,1)]        
+        [(2,1)]         10    [(2,1)]         10    [(2,1)]        
+        [(2,1)]         10    [(2,1)]         10    [(2,1)]        
+        [(2,1)]         10    [(2,1)]         10    [(2,1)]        
+        [(2,1)]         10    [(2,1)]         10    [(2,1)]        
+        [(2,1)]         10    [(2,1)]         10    [(2,1)]        
+        [(2,1)]         10    [(2,1)]         10    [(2,1)]        
         []              68    []              68    []             
         []              160   []              160   []             
@@ -821,6 +774,6 @@
         []              10    []              10    []             
         []              10    []              10    []             
-        [[2, 1, 0]]     10    [[2, 1, 0]]     10    [[2, 1, 0]]    
-        [[2, 1, 0]]     10    [[2, 1, 0]]     10    [[2, 1, 0]]    
+        [(2,3)]         10    [(2,3)]         10    [(2,3)]        
+        [(2,3)]         10    [(2,3)]         10    [(2,3)]        
         []              160   []              160   []             
         []              68    []              68    []             
@@ -828,15 +781,15 @@
         []              68    []              68    []             
         []              10    []              10    []             
-        [[2, 1, 0]]     160   [[2, 1, 0]]     160   [[2, 1, 0]]    
-        []              10    []              10    []             
-        []              10    []              10    []             
-        [[2, 1, 0]]     160   [[2, 1, 0]]     160   [[2, 1, 0]]    
-        []              10    []              10    []             
-        [[2, 1, 0]]     10    [[2, 1, 0]]     10    [[2, 1, 0]]    
-        [[2, 1, 0]]     10    [[2, 1, 0]]     10    [[2, 1, 0]]    
-        [[2, 1, 0]]     10    [[2, 1, 0]]     10    [[2, 1, 0]]    
-        [[2, 1, 0]]     10    [[2, 1, 0]]     10    [[2, 1, 0]]    
-        [[2, 1, 0]]     10    [[2, 1, 0]]     10    [[2, 1, 0]]    
-        [[2, 1, 0]]     10    [[2, 1, 0]]     10    [[2, 1, 0]]    
+        [(2,3)]         160   [(2,3)]         160   [(2,3)]        
+        []              10    []              10    []             
+        []              10    []              10    []             
+        [(2,3)]         160   [(2,3)]         160   [(2,3)]        
+        []              10    []              10    []             
+        [(2,3)]         10    [(2,3)]         10    [(2,3)]        
+        [(2,3)]         10    [(2,3)]         10    [(2,3)]        
+        [(2,3)]         10    [(2,3)]         10    [(2,3)]        
+        [(2,3)]         10    [(2,3)]         10    [(2,3)]        
+        [(2,3)]         10    [(2,3)]         10    [(2,3)]        
+        [(2,3)]         10    [(2,3)]         10    [(2,3)]        
         []              78    []              78    []             
         []              170   []              170   []             
@@ -849,18 +802,18 @@
         []              228   []              228   []             
         []              228   []              228   []             
-        [[1, 0, 2]]     228   [[1, 0, 2]]     228   [[1, 0, 2]]    
-        [[1, 0, 2]]     228   [[1, 0, 2]]     228   [[1, 0, 2]]    
-        [[1, 0, 2]]     78    [[1, 0, 2]]     78    [[1, 0, 2]]    
-        []              170   []              170   []             
-        [[1, 0, 2]]     78    [[1, 0, 2]]     78    [[1, 0, 2]]    
-        []              170   []              170   []             
-        []              170   []              170   []             
-        []              170   []              170   []             
-        [[1, 0, 2]]     78    [[1, 0, 2]]     78    [[1, 0, 2]]    
-        [[1, 0, 2]]     78    [[1, 0, 2]]     78    [[1, 0, 2]]    
-        [[1, 0, 2]]     78    [[1, 0, 2]]     78    [[1, 0, 2]]    
-        [[1, 0, 2]]     78    [[1, 0, 2]]     78    [[1, 0, 2]]    
-        [[1, 0, 2]]     78    [[1, 0, 2]]     78    [[1, 0, 2]]    
-        [[1, 0, 2]]     78    [[1, 0, 2]]     78    [[1, 0, 2]]    
+        [(1,3)]         228   [(1,3)]         228   [(1,3)]        
+        [(1,3)]         228   [(1,3)]         228   [(1,3)]        
+        [(1,3)]         78    [(1,3)]         78    [(1,3)]        
+        []              170   []              170   []             
+        [(1,3)]         78    [(1,3)]         78    [(1,3)]        
+        []              170   []              170   []             
+        []              170   []              170   []             
+        []              170   []              170   []             
+        [(1,3)]         78    [(1,3)]         78    [(1,3)]        
+        [(1,3)]         78    [(1,3)]         78    [(1,3)]        
+        [(1,3)]         78    [(1,3)]         78    [(1,3)]        
+        [(1,3)]         78    [(1,3)]         78    [(1,3)]        
+        [(1,3)]         78    [(1,3)]         78    [(1,3)]        
+        [(1,3)]         78    [(1,3)]         78    [(1,3)]        
         []              160   []              160   []             
         []              68    []              68    []             
@@ -873,18 +826,18 @@
         []              10    []              10    []             
         []              10    []              10    []             
-        [[1, 0, 2]]     10    [[1, 0, 2]]     10    [[1, 0, 2]]    
-        [[1, 0, 2]]     10    [[1, 0, 2]]     10    [[1, 0, 2]]    
-        [[1, 0, 2]]     160   [[1, 0, 2]]     160   [[1, 0, 2]]    
-        []              10    []              10    []             
-        [[1, 0, 2]]     160   [[1, 0, 2]]     160   [[1, 0, 2]]    
-        []              10    []              10    []             
-        []              10    []              10    []             
-        []              10    []              10    []             
-        [[1, 0, 2]]     10    [[1, 0, 2]]     10    [[1, 0, 2]]    
-        [[1, 0, 2]]     10    [[1, 0, 2]]     10    [[1, 0, 2]]    
-        [[1, 0, 2]]     10    [[1, 0, 2]]     10    [[1, 0, 2]]    
-        [[1, 0, 2]]     10    [[1, 0, 2]]     10    [[1, 0, 2]]    
-        [[1, 0, 2]]     10    [[1, 0, 2]]     10    [[1, 0, 2]]    
-        [[1, 0, 2]]     10    [[1, 0, 2]]     10    [[1, 0, 2]]    
+        [(1,3)]         10    [(1,3)]         10    [(1,3)]        
+        [(1,3)]         10    [(1,3)]         10    [(1,3)]        
+        [(1,3)]         160   [(1,3)]         160   [(1,3)]        
+        []              10    []              10    []             
+        [(1,3)]         160   [(1,3)]         160   [(1,3)]        
+        []              10    []              10    []             
+        []              10    []              10    []             
+        []              10    []              10    []             
+        [(1,3)]         10    [(1,3)]         10    [(1,3)]        
+        [(1,3)]         10    [(1,3)]         10    [(1,3)]        
+        [(1,3)]         10    [(1,3)]         10    [(1,3)]        
+        [(1,3)]         10    [(1,3)]         10    [(1,3)]        
+        [(1,3)]         10    [(1,3)]         10    [(1,3)]        
+        [(1,3)]         10    [(1,3)]         10    [(1,3)]        
         []              170   []              170   []             
         []              78    []              78    []             
@@ -893,99 +846,101 @@
         []              228   []              228   []             
         []              228   []              228   []             
-        [[2, 1, 0]]     228   [[2, 1, 0]]     228   [[2, 1, 0]]    
-        [[2, 1, 0]]     228   [[2, 1, 0]]     228   [[2, 1, 0]]    
-        []              78    []              78    []             
-        []              170   []              170   []             
-        []              78    []              78    []             
-        []              78    []              78    []             
-        []              170   []              170   []             
-        [[2, 1, 0]]     78    [[2, 1, 0]]     78    [[2, 1, 0]]    
-        []              170   []              170   []             
-        []              170   []              170   []             
-        [[2, 1, 0]]     78    [[2, 1, 0]]     78    [[2, 1, 0]]    
-        []              170   []              170   []             
-        [[2, 1, 0]]     78    [[2, 1, 0]]     78    [[2, 1, 0]]    
-        [[2, 1, 0]]     78    [[2, 1, 0]]     78    [[2, 1, 0]]    
-        [[2, 1, 0]]     78    [[2, 1, 0]]     78    [[2, 1, 0]]    
-        [[2, 1, 0]]     78    [[2, 1, 0]]     78    [[2, 1, 0]]    
-        [[2, 1, 0]]     78    [[2, 1, 0]]     78    [[2, 1, 0]]    
-        [[2, 1, 0]]     78    [[2, 1, 0]]     78    [[2, 1, 0]]    
+        [(2,3)]         228   [(2,3)]         228   [(2,3)]        
+        [(2,3)]         228   [(2,3)]         228   [(2,3)]        
+        []              78    []              78    []             
+        []              170   []              170   []             
+        []              78    []              78    []             
+        []              78    []              78    []             
+        []              170   []              170   []             
+        [(2,3)]         78    [(2,3)]         78    [(2,3)]        
+        []              170   []              170   []             
+        []              170   []              170   []             
+        [(2,3)]         78    [(2,3)]         78    [(2,3)]        
+        []              170   []              170   []             
+        [(2,3)]         78    [(2,3)]         78    [(2,3)]        
+        [(2,3)]         78    [(2,3)]         78    [(2,3)]        
+        [(2,3)]         78    [(2,3)]         78    [(2,3)]        
+        [(2,3)]         78    [(2,3)]         78    [(2,3)]        
+        [(2,3)]         78    [(2,3)]         78    [(2,3)]        
+        [(2,3)]         78    [(2,3)]         78    [(2,3)]        
         []              228   []              228   []             
         []              228   []              228   []             
-        [[0, 2, 1]]     228   [[0, 2, 1]]     228   [[0, 2, 1]]    
-        [[0, 2, 1]]     228   [[0, 2, 1]]     228   [[0, 2, 1]]    
-        []              170   []              170   []             
-        []              78    []              78    []             
-        []              78    []              78    []             
-        []              78    []              78    []             
-        []              170   []              170   []             
-        []              78    []              78    []             
-        []              78    []              78    []             
-        []              78    []              78    []             
-        []              170   []              170   []             
-        []              170   []              170   []             
-        []              170   []              170   []             
-        [[0, 2, 1]]     78    [[0, 2, 1]]     78    [[0, 2, 1]]    
-        []              170   []              170   []             
-        [[0, 2, 1]]     78    [[0, 2, 1]]     78    [[0, 2, 1]]    
-        [[0, 2, 1]]     78    [[0, 2, 1]]     78    [[0, 2, 1]]    
-        [[0, 2, 1]]     78    [[0, 2, 1]]     78    [[0, 2, 1]]    
-        [[0, 2, 1]]     78    [[0, 2, 1]]     78    [[0, 2, 1]]    
-        [[0, 2, 1]]     78    [[0, 2, 1]]     78    [[0, 2, 1]]    
-        [[0, 2, 1]]     78    [[0, 2, 1]]     78    [[0, 2, 1]]    
-        [[0, 2, 1]]     78    [[0, 2, 1]]     78    [[0, 2, 1]]    
+        [(2,1)]         228   [(2,1)]         228   [(2,1)]        
+        [(2,1)]         228   [(2,1)]         228   [(2,1)]        
+        []              170   []              170   []             
+        []              78    []              78    []             
+        []              78    []              78    []             
+        []              78    []              78    []             
+        []              170   []              170   []             
+        []              78    []              78    []             
+        []              78    []              78    []             
+        []              78    []              78    []             
+        []              170   []              170   []             
+        []              170   []              170   []             
+        []              170   []              170   []             
+        [(2,1)]         78    [(2,1)]         78    [(2,1)]        
+        []              170   []              170   []             
+        [(2,1)]         78    [(2,1)]         78    [(2,1)]        
+        [(2,1)]         78    [(2,1)]         78    [(2,1)]        
+        [(2,1)]         78    [(2,1)]         78    [(2,1)]        
+        [(2,1)]         78    [(2,1)]         78    [(2,1)]        
+        [(2,1)]         78    [(2,1)]         78    [(2,1)]        
+        [(2,1)]         78    [(2,1)]         78    [(2,1)]        
+        [(2,1)]         78    [(2,1)]         78    [(2,1)]        
         []              238   []              238   []             
         []              238   []              238   []             
-        [[0, 2, 1]]     238   [[0, 2, 1]]     238   [[0, 2, 1]]    
-        [[0, 2, 1]]     238   [[0, 2, 1]]     238   [[0, 2, 1]]    
+        [(2,1)]         238   [(2,1)]         238   [(2,1)]        
+        [(2,1)]         238   [(2,1)]         238   [(2,1)]        
         []              238   []              238   []             
         []              238   []              238   []             
-        [[2, 1, 0]]     238   [[2, 1, 0]]     238   [[2, 1, 0]]    
-        [[2, 1, 0]]     238   [[2, 1, 0]]     238   [[2, 1, 0]]    
+        [(2,3)]         238   [(2,3)]         238   [(2,3)]        
+        [(2,3)]         238   [(2,3)]         238   [(2,3)]        
         []              238   []              238   []             
         []              238   []              238   []             
-        [[1, 0, 2]]     238   [[1, 0, 2]]     238   [[1, 0, 2]]    
-        [[1, 0, 2]]     238   [[1, 0, 2]]     238   [[1, 0, 2]]    
-        [[1, 0, 2]]     238   [[1, 0, 2]]     238   [[1, 0, 2]]    
-        [[2, 1, 0]]     238   [[2, 1, 0]]     238   [[2, 1, 0]]    
-        [[1, 0, 2]]     238   [[1, 0, 2]]     238   [[1, 0, 2]]    
-        [[0, 2, 1]]     238   [[0, 2, 1]]     238   [[0, 2, 1]]    
-        [[2, 1, 0]]     238   [[2, 1, 0]]     238   [[2, 1, 0]]    
-        [[0, 2, 1]]     238   [[0, 2, 1]]     238   [[0, 2, 1]]    
-        [[0, 2, 1], [1, 0, 2]] 238   [[0, 2, 1], [1, 0, 2]] 238   [[0, 2, 1], [1, 0, 2]]
-        [[0, 2, 1], [1, 0, 2]] 238   [[0, 2, 1], [1, 0, 2]] 238   [[0, 2, 1], [1, 0, 2]]
-        [[0, 2, 1], [1, 0, 2]] 238   [[0, 2, 1], [1, 0, 2]] 238   [[0, 2, 1], [1, 0, 2]]
-        [[0, 2, 1], [1, 0, 2]] 238   [[0, 2, 1], [1, 0, 2]] 238   [[0, 2, 1], [1, 0, 2]]
-        [[0, 2, 1], [1, 0, 2]] 238   [[0, 2, 1], [1, 0, 2]] 238   [[0, 2, 1], [1, 0, 2]]
-        [[0, 2, 1], [1, 0, 2]] 238   [[0, 2, 1], [1, 0, 2]] 238   [[0, 2, 1], [1, 0, 2]] 
+        [(1,3)]         238   [(1,3)]         238   [(1,3)]        
+        [(1,3)]         238   [(1,3)]         238   [(1,3)]        
+        [(1,3)]         238   [(1,3)]         238   [(1,3)]        
+        [(2,3)]         238   [(2,3)]         238   [(2,3)]        
+        [(1,3)]         238   [(1,3)]         238   [(1,3)]        
+        [(2,1)]         238   [(2,1)]         238   [(2,1)]        
+        [(2,3)]         238   [(2,3)]         238   [(2,3)]        
+        [(2,1)]         238   [(2,1)]         238   [(2,1)]        
+        [(2,1), (1,3)]  238   [(2,1), (1,3)]  238   [(2,1), (1,3)] 
+        [(2,1), (1,3)]  238   [(2,1), (1,3)]  238   [(2,1), (1,3)] 
+        [(2,1), (1,3)]  238   [(2,1), (1,3)]  238   [(2,1), (1,3)] 
+        [(2,1), (1,3)]  238   [(2,1), (1,3)]  238   [(2,1), (1,3)] 
+        [(2,1), (1,3)]  238   [(2,1), (1,3)]  238   [(2,1), (1,3)] 
+        [(2,1), (1,3)]  238   [(2,1), (1,3)]  238   [(2,1), (1,3)] 
 
         sage: C = graphs.CubeGraph(1)
         sage: gens = search_tree(C, [C.vertices()], lab=False)
-        sage: PermutationGroup([perm_group_elt(aa) for aa in gens]).order()
+        sage: PermutationGroup(gens).order()
         2
         sage: C = graphs.CubeGraph(2)
         sage: gens = search_tree(C, [C.vertices()], lab=False)
-        sage: PermutationGroup([perm_group_elt(aa) for aa in gens]).order()
+        sage: PermutationGroup(gens).order()
         8
         sage: C = graphs.CubeGraph(3)
         sage: gens = search_tree(C, [C.vertices()], lab=False)
-        sage: PermutationGroup([perm_group_elt(aa) for aa in gens]).order()
+        sage: PermutationGroup(gens).order()
         48
         sage: C = graphs.CubeGraph(4)
         sage: gens = search_tree(C, [C.vertices()], lab=False)
-        sage: PermutationGroup([perm_group_elt(aa) for aa in gens]).order()
+        sage: PermutationGroup(gens).order()
         384
         sage: C = graphs.CubeGraph(5)
-        sage: gens = search_tree(C, [C.vertices()], lab=False)  # long time (~8 secs)
-        sage: PermutationGroup([perm_group_elt(aa) for aa in gens]).order()                    # long time
+        sage: gens = search_tree(C, [C.vertices()], lab=False)  # long time
+        sage: PermutationGroup(gens).order()                    # long time
         3840
         sage: C = graphs.CubeGraph(6)
-        sage: gens = search_tree(C, [C.vertices()], lab=False)  # long time (~50 secs)
-        sage: PermutationGroup([perm_group_elt(aa) for aa in gens]).order()                    # long time
+        sage: gens = search_tree(C, [C.vertices()], lab=False)  # long time
+        sage: PermutationGroup(gens).order()                    # long time
         46080
     """
     from copy import copy
+    from sage.groups.perm_gps.permgroup import SymmetricGroup
     from sage.rings.infinity import Infinity
     n = G.order()
+    S = SymmetricGroup(n)
     Pi = copy(Pi)
     
@@ -1118,5 +1073,5 @@
             elif k < hzf: state = 8 ## BDM had !=, broke at G = Graph({0:[],1:[],2:[]}), Pi = [[0,1,2]]
             else:
-                gamma = get_permutation(eta.values(), nu.values(), list_perm=True)
+                gamma = get_permutation(eta.values(), nu.values())
     #            print gamma
                 if G == G.relabel(gamma, inplace=False): # if G^gamma == G:
@@ -1128,8 +1083,8 @@
             if (not lab) or (qzb < 0): state = 6
             elif (qzb > 0) or (k < len(rho)): state = 9
-            elif (term_pnest_graph(G, nu.values(), enumer=True) > term_pnest_graph(G, rho.values(), enumer=True)): state = 9
-            elif (term_pnest_graph(G, nu.values(), enumer=True) < term_pnest_graph(G, rho.values(), enumer=True)): state = 6
+            elif (term_pnest_graph(G, nu.values()) > term_pnest_graph(G, rho.values())): state = 9
+            elif (term_pnest_graph(G, nu.values()) < term_pnest_graph(G, rho.values())): state = 6
             else:
-                gamma = get_permutation(nu.values(), rho.values(), list_perm=True)
+                gamma = get_permutation(nu.values(), rho.values())
     #            print gamma
                 state = 10
@@ -1145,10 +1100,10 @@
 #            print 'state: 10'
             l = min([l+1,L])
-            Omega[l] = min_cell_reps(orbit_partition(gamma, list_perm=True))
-            Phi[l] = fix(orbit_partition(gamma, list_perm=True))
-            if finer( orbit_partition(gamma, list_perm=True), Theta ):
+            Omega[l] = min_cell_reps(orbit_partition(G, gamma))
+            Phi[l] = fix(orbit_partition(G, gamma))
+            if finer( orbit_partition(G, gamma), Theta ):
                 state = 11
             else:
-                Theta = vee( orbit_partition(gamma, list_perm=True), Theta )
+                Theta = vee( orbit_partition(G, gamma), Theta )
                 output.append(gamma)
                 if tvc in min_cell_reps(Theta) and lab: ## added "and lab"
@@ -1274,26 +1229,4 @@
         return output
 
-def perm_group_elt(lperm):
-    """
-    Given a list permutation of the set {0, 1, ..., n-1},
-    returns the corresponding PermutationGroupElement where
-    we take 0 = n.
-    """
-    from sage.groups.perm_gps.permgroup import SymmetricGroup
-    n = len(lperm)
-    S = SymmetricGroup(n)
-    Part = orbit_partition(lperm, list_perm=True)
-    gens = []
-    for z in Part:
-        if len(z) > 1:
-            if 0 in z:
-                zed = z.index(0)
-                generator = z[:zed] + [n] + z[zed+1:]
-                gens.append(tuple(generator))
-            else:
-                gens.append(tuple(z))
-    E = S(gens)
-    return E
-
 # Benchmarking functions
 
@@ -1310,5 +1243,5 @@
         sage: Glist = {}
         sage: Giso  = {}
-        sage: for n in range(1,5): # long time (~9 secs)
+        sage: for n in range(1,5): # long time
         ...    Glist[n] = all_labeled_graphs(n)
         ...    Giso[n] = []
@@ -1393,5 +1326,5 @@
         sage: Glist = {}
         sage: Giso  = {}
-        sage.: for n in range(1,4): # long time (~130 secs)
+        sage: for n in range(1,4): # long time
         ...    Glist[n] = all_labeled_digraphs_with_loops(n)
         ...    Giso[n] = []
@@ -1404,5 +1337,5 @@
         ...        if not inn:
         ...            Giso[n].append(b)
-        sage.: for n in Giso: # long time (depends on previous)
+        sage: for n in Giso: # long time (depends on previous)
         ...    print n, len(Giso[n])
         1 2
Index: sage/graphs/graph_list.py
===================================================================
--- sage/graphs/graph_list.py	(revision 3734)
+++ sage/graphs/graph_list.py	(revision 3586)
@@ -58,5 +58,5 @@
         sage: l = ['N@@?N@UGAGG?gGlKCMO','XsGGWOW?CC?C@HQKHqOjYKC_uHWGX?P?~TqIKA`OA@SAOEcEA??']
         sage: graphs_list.from_graph6(l)
-        [Graph on 14 vertices, Graph on 25 vertices]
+        [A graph on 14 vertices, A graph on 25 vertices]
     """
     from sage.graphs.graph import Graph
@@ -99,5 +99,5 @@
         sage: l = [':P_`cBaC_ACd`C_@BC`ABDHaEH_@BF_@CHIK_@BCEHKL_BIKM_BFGHI',':f`??KO?B_OOSCGE_?OWONDBO?GOJBDO?_SSJdApcOIG`?og_UKEbg?_SKFq@[CCBA`p?oYMFp@gw]Qaa@xEMHDb@hMCBCbQ@ECHEcAKKQKFPOwo[PIDQ{KIHEcQPOkVKEW_WMNKqPWwcRKOOWSKIGCqhWt??___WMJFCahWzEBa`xOu[MpPPKqYNoOOOKHHDBPs|??__gWMKEcAHKgTLErqA?A@a@G{kVLErs?GDBA@XCs\\NggWSOJIDbHh@?A@aF']
         sage: graphs_list.from_sparse6(l)
-        [Looped multi-graph on 17 vertices, Looped multi-graph on 39 vertices]
+        [A looped multi-graph on 17 vertices, A looped multi-graph on 39 vertices]
     """
     from sage.graphs.graph import Graph
Index: sage/groups/abelian_gps/dual_abelian_group_element.py
===================================================================
--- sage/groups/abelian_gps/dual_abelian_group_element.py	(revision 4063)
+++ sage/groups/abelian_gps/dual_abelian_group_element.py	(revision 3290)
@@ -270,6 +270,5 @@
         if is_ComplexField(F):
             I = F.gen()
-            PI = F(pi)
-            ans = prod([exp(2*PI*I*expsX[i]*expsg[i]/invs[i]) for i in range(len(expsX))])
+            ans = prod([exp(2*pi*I*expsX[i]*expsg[i]/invs[i]) for i in range(len(expsX))])
             return ans
         ans = F(1)  ## assumes F is the cyclotomic field
Index: sage/groups/group.pyx
===================================================================
--- sage/groups/group.pyx	(revision 3977)
+++ sage/groups/group.pyx	(revision 2419)
@@ -121,20 +121,4 @@
         return True
 
-    def cayley_graph(self):
-        from sage.graphs.graph import DiGraph
-        arrows = {}
-        for g in self:
-            for s in self.gens():
-                gs = g*s
-                if not gs == g:
-                    try:
-                        _ = arrows[g]
-                    except KeyError:
-                        arrows[g] = {}
-
-                    arrows[g][gs] = s
-
-        return DiGraph(arrows)
-
 cdef class AlgebraicGroup(Group):
     """
Index: sage/gsl/dft.py
===================================================================
--- sage/gsl/dft.py	(revision 4063)
+++ sage/gsl/dft.py	(revision 3627)
@@ -67,6 +67,8 @@
 from sage.rings.real_mpfr import RR
 from sage.rings.all import CC, I
-from sage.calculus.all import sin, cos
-from sage.functions.constants import pi
+from math import sin
+from math import cos
+from sage.functions.constants import Pi
+pi = Pi()
 from sage.gsl.fft import FastFourierTransform
 from sage.gsl.dwt import WaveletTransform
@@ -317,7 +319,6 @@
         J = self.index_object()   ## must be = range(N)
         N = len(J)
-        S = self.list()
-        PI = F(pi)
-        FT = [sum([S[i]*cos(2*PI*i/N) for i in J]) for j in J]
+        S = self.list()        
+        FT = [sum([S[i]*cos(2*pi*i/N) for i in J]) for j in J]
         return IndexedSequence(FT,J)
 
@@ -328,5 +329,4 @@
         EXAMPLES:
             sage: J = range(5)
-            sage: I = CC.0; pi = CC(pi)
             sage: A = [exp(-2*pi*i*I/5) for i in J]
             sage: s = IndexedSequence(A,J)
@@ -338,7 +338,6 @@
         J = self.index_object()   ## must be = range(N)
         N = len(J)
-        S = self.list()
-        PI = F(pi)
-        FT = [sum([S[i]*sin(2*PI*i/N) for i in J]) for j in J]
+        S = self.list()        
+        FT = [sum([S[i]*sin(2*pi*i/N) for i in J]) for j in J]
         return IndexedSequence(FT,J)
 
Index: sage/gsl/integration.pyx
===================================================================
--- sage/gsl/integration.pyx	(revision 4062)
+++ sage/gsl/integration.pyx	(revision 3365)
@@ -75,5 +75,5 @@
 
       We check this with a symbolic integration:
-         sage: (sin(x)^3+sin(x)).integral(x,0,pi)
+         sage: maxima('sin(x)^3+sin(x)').integral(x,0,pi)
          10/3
 
@@ -95,5 +95,5 @@
                rule=4: 41 pt rule
                rule=5: 51 pt rule
-               rule=6: 61 pt rule
+               rule=6: 61 pt sule
          Higher key values are more accurate for smooth functions but lower
          key values deal better with discontinuities.
@@ -102,10 +102,4 @@
        numerical_integral returns a tuple whose first component is
        the answer and whose second component is an error estimate.
-
-   REMARK:
-       There is also a method \code{nintegral} on symbolic expressions
-       that implements numerical integration using Maxima.  It is potentially
-       very useful for symbolic expressions.
-   
 
    MORE EXAMPLES:
@@ -144,16 +138,10 @@
 
    One can integrate any real-valued callable function:
-       sage: numerical_integral(lambda x: abs(zeta(x)), [1.1,1.5])           # slightly random output
+       sage: numerical_integral(zeta, [1.1,1.5])           # slightly random output
        (1.8488570602160455, 2.052643677492633e-14)
-
-   We can also numerically integrate symbolic expressions using either this
-   function (which uses GSL) or the native integration (which uses Maxima):
-       sage: exp(-1/x).nintegral(x, 1, 2)   # via maxima
-       (0.50479221787318396, 5.6043194293440752e-15, 21, 0)
-       sage: numerical_integral(exp(-1/x), 1, 2)
-       (0.50479221787318407, 5.6043194293440744e-15)
+       
        
    IMPLEMENTATION NOTES:
-       Uses calls to the GSL -- the GNU Scientific Library -- C library.
+       Uses GSL -- the GNU Scientific Library
 
    AUTHORS:
Index: sage/interfaces/all.py
===================================================================
--- sage/interfaces/all.py	(revision 3690)
+++ sage/interfaces/all.py	(revision 3117)
@@ -18,5 +18,4 @@
 from mathematica import mathematica, mathematica_console, Mathematica
 from matlab import matlab, matlab_console, matlab_version, Matlab
-from mupad import mupad, mupad_console, Mupad  # NOT functional yet
 from mwrank import mwrank, Mwrank, mwrank_console
 from octave import octave, octave_console, octave_version, Octave
Index: sage/interfaces/cleaner.py
===================================================================
--- sage/interfaces/cleaner.py	(revision 4016)
+++ sage/interfaces/cleaner.py	(revision 2973)
@@ -1,5 +1,2 @@
-"""nodoctest
-"""
-
 ###############################################################################
 #   SAGE: System for Algebra and Geometry Experimentation    
@@ -18,7 +15,6 @@
 F = '%s/spawned_processes'%misc.SAGE_TMP
 
-def cleaner(pid, cmd=''):
-    if cmd != '':
-        cmd = cmd.strip().split()[0]
+def cleaner(pid, cmd):
+    cmd = cmd.strip().split()[0]
     # This is safe, since only this process writes to this file.
     if os.path.exists(F):
Index: sage/interfaces/expect.py
===================================================================
--- sage/interfaces/expect.py	(revision 4061)
+++ sage/interfaces/expect.py	(revision 3117)
@@ -72,10 +72,4 @@
 os.environ['PATH'] = ':'.join([v for v in p if v.strip() != '.'])
 
-class AsciiArtString(str):
-    def __init__(self, x):
-        str.__init__(self, x)
-        
-    def __repr__(self):
-        return str(self)
     
 
@@ -345,7 +339,7 @@
                 self._expect.close = dummy
             except Exception, msg:
-                pass
+                print msg
         except Exception, msg:
-            pass
+            print msg
 
     def cputime(self):
@@ -356,18 +350,4 @@
 
     def quit(self, verbose=False):
-        """
-        EXAMPLES:
-            sage: a = maxima('y')
-            sage: a
-            y
-            sage: maxima.quit()
-            sage: a        # since the representation is cached
-            y
-            sage: a._check_valid()
-            Traceback (most recent call last):
-            ...
-            ValueError: The maxima session in which this object was defined is no longer running.
-        """
-        self._session_number += 1
         if self._expect is None:
             return
@@ -376,16 +356,18 @@
         # by shell scripts, and killing the shell script doesn't
         # kill the binary.
-        E = self._expect
         if verbose:
             print "Exiting spawned %s process."%self
         try:
-            E.sendline(self._quit_string())
+            self._expect.sendline(self._quit_string())
             self._so_far(wait=0.25)
-            os.killpg(E.pid, 9)
-            os.kill(E.pid, 9)
-        except (RuntimeError, OSError), msg:
+            os.killpg(self._expect.pid, 9)
+            os.kill(self._expect.pid, 9)
+        except OSError, msg:
             pass
+        #try:
+        #    self._expect.close(9)
+        #except Exception:
+        #    pass
         self._expect = None
-        return
 
     def _quit_string(self):
@@ -473,28 +455,4 @@
             raise KeyboardInterrupt, "Ctrl-c pressed while running %s"%self
 
-    def interrupt(self, tries=20, timeout=0.3):
-        E = self._expect
-        if E is None:
-            return True
-        success = False
-        try:
-            for i in range(tries):
-                E.sendline(self._quit_string())
-                E.sendline(chr(3))
-                try:
-                    E.expect(self._prompt, timeout=timeout)
-                    success= True
-                    break
-                except (pexpect.TIMEOUT, pexpect.EOF), msg:
-                    #print msg
-                    pass
-        except Exception, msg:
-            pass
-        if success:
-            pass
-        else:
-            self.quit()
-        return success
-        
     def eval(self, code, strip=True):
         """
@@ -504,6 +462,5 @@
                      (ignored in the base class).
         """
-        if not isinstance(code, str):
-            raise TypeError, 'input code must be a string.'
+        code = str(code)
         code = code.strip()
         try:
@@ -512,5 +469,5 @@
             self._keyboard_interrupt()
         except TypeError, s:
-            raise TypeError, 'error evaluating "%s":\n%s'%(code,s)
+            return 'error evaluating "%s":\n%s'%(code,s)
 
     def execute(self, *args, **kwds):
@@ -783,5 +740,5 @@
 
     def _reduce(self):
-        return repr(self)
+        return str(self)
 
     def _r_action(self, x):   # used for coercion
@@ -824,6 +781,6 @@
         try:
             P = self.parent()
-            if P is None or P._session_number == BAD_SESSION or self._session_number == -1 or \
-                          P._session_number != self._session_number:
+            if P is None is None or P._session_number == BAD_SESSION or self._session_number == -1 or \
+                          (P._restart_on_ctrlc and P._session_number != self._session_number):
                 raise ValueError, "The %s session in which this object was defined is no longer running."%P.name()
         except AttributeError:
Index: sage/interfaces/gap.py
===================================================================
--- sage/interfaces/gap.py	(revision 4059)
+++ sage/interfaces/gap.py	(revision 3634)
@@ -592,7 +592,4 @@
         return s
 
-    def __nonzero__(self):
-        return self.bool()
-
     def __len__(self):
         """
Index: sage/interfaces/macaulay2.py
===================================================================
--- sage/interfaces/macaulay2.py	(revision 4059)
+++ sage/interfaces/macaulay2.py	(revision 3157)
@@ -96,5 +96,5 @@
 import os
 
-from expect import Expect, ExpectElement, AsciiArtString
+from expect import Expect, ExpectElement
 
 from sage.misc.misc import verbose
@@ -161,5 +161,5 @@
         if strip:
             ans = remove_output_labels(ans)
-        return AsciiArtString(ans)
+        return ans
             
 
@@ -377,7 +377,7 @@
             return self.parent().new('%s %% %s'%(self.name(), x.name()))
 
-    def __nonzero__(self):
+    def is_zero(self):
         P = self.parent()
-        return P.eval('%s == 0'%self.name()) == 'false'        
+        return P.eval('%s == 0'%self.name()) == 'true'        
 
     def sage_polystring(self):
Index: sage/interfaces/maple.py
===================================================================
--- sage/interfaces/maple.py	(revision 3690)
+++ sage/interfaces/maple.py	(revision 3134)
@@ -260,5 +260,5 @@
     def _install_hints(self):
         """
-        Hints for installing Maple on your computer.
+        Hints for installing mathematica on your computer.
 
         AUTHOR:
Index: sage/interfaces/mathematica.py
===================================================================
--- sage/interfaces/mathematica.py	(revision 4026)
+++ sage/interfaces/mathematica.py	(revision 2124)
@@ -78,7 +78,7 @@
 
     sage: c = m(5)
-    sage: print m('b + c x')
+    sage: m('b + c x')
                  b + c x
-    sage: print m('b') + c*m('x')
+    sage: m('b') + c*m('x')
              b + 5 x
 
@@ -182,5 +182,5 @@
 
     sage: x = mathematica(pi/2)
-    sage: print x
+    sage: x
              Pi
              --
@@ -193,4 +193,10 @@
     sage: loads(dumps(n)) == n
     True
+
+This example illustrates saving to a file in the local directory
+and to one in the \sage database directory.
+
+    sage.: n.save('n')
+    sage.: n.db('n')
 
 AUTHOR:
@@ -216,6 +222,5 @@
 import os
 
-from expect import (Expect, ExpectElement, ExpectFunction,
-                    FunctionElement, AsciiArtString)
+from expect import Expect, ExpectElement, ExpectFunction, FunctionElement
 
 from sage.misc.misc import verbose
@@ -316,7 +321,7 @@
         s = Expect.eval(self, code)
         if strip:
-            return AsciiArtString(clean_output(s))
+            return clean_output(s)
         else:
-            return AsciiArtString(s)
+            return s
 
     #def _keyboard_interrupt(self):
@@ -436,9 +441,9 @@
     def __repr__(self):
         P = self._check_valid()
-        return P.get(self._name, ascii_art=False).strip()
+        return P.get(self._name, ascii_art=True)
 
     def __str__(self):
         P = self._check_valid()
-        return P.get(self._name, ascii_art=True)
+        return P.get(self._name, ascii_art=False).strip()
 
     def str(self):
Index: sage/interfaces/maxima.py
===================================================================
--- sage/interfaces/maxima.py	(revision 4058)
+++ sage/interfaces/maxima.py	(revision 3622)
@@ -32,29 +32,37 @@
     sage: F = maxima.factor('x^5 - y^5')
     sage: F
-    -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
+    -(y - x)*(y^4 + x*y^3 + x^2*y^2 + x^3*y + x^4)
     sage: type(F)
     <class 'sage.interfaces.maxima.MaximaElement'>
 
 Note that Maxima objects can also be displayed using ``ASCII art'';
-to see a normal linear representation of any Maxima object x.
-Just use the print command:
+to see a normal linear representation of any Maxima object x,
 use \code{str(x)}.
-    sage: print F
+    sage: F.display2d()
                                4      3    2  2    3      4
                    - (y - x) (y  + x y  + x  y  + x  y + x )
 
-You can always use \code{repr(x)} to obtain the linear representation
-of an object.  This can be useful for moving maxima data to other
-systems.
-    sage: repr(F)
-    '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'
+We can make this the default:
+    sage: maxima.display2d(True)
+    sage: F
+                               4      3    2  2    3      4
+                   - (y - x) (y  + x y  + x  y  + x  y + x )
+
+You can always use \code{x.str()} to obtain the linear representation
+of an object, even without changing the display2d flag.  This can
+be useful for moving maxima data to other systems. 
     sage: F.str()
-    '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'
+    '-(y - x)*(y^4 + x*y^3 + x^2*y^2 + x^3*y + x^4)'
     
+    sage: maxima.display2d(False)
+    sage: F
+    -(y - x)*(y^4 + x*y^3 + x^2*y^2 + x^3*y + x^4)
+
+
 The \code{maxima.eval} command evaluates an expression in maxima
-and returns the result as a \emph{string} not a maxima object.
+and returns the result as a string.
 
     sage: print maxima.eval('factor(x^5 - y^5)')
-    -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
+    -(y - x)*(y^4 + x*y^3 + x^2*y^2 + x^3*y + x^4)
 
 We can create the polynomial $f$ as a Maxima polynomial, then call
@@ -63,7 +71,7 @@
     sage: f = maxima('x^5 - y^5')
     sage: f^2
-    (x^5-y^5)^2
+    (x^5 - y^5)^2
     sage: f.factor()
-    -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
+    -(y - x)*(y^4 + x*y^3 + x^2*y^2 + x^3*y + x^4)
 
 Control-C interruption works well with the maxima interface,
@@ -82,7 +90,7 @@
 
     sage: a = maxima('(1 + sqrt(2))^5'); a
-    (sqrt(2)+1)^5
+    (sqrt(2) + 1)^5
     sage: a.expand()
-    29*sqrt(2)+41
+    29*sqrt(2) + 41
 
     sage: a = maxima('(1 + sqrt(2))^5')
@@ -102,22 +110,22 @@
     sage: f = maxima('(x + 3*y + x^2*y)^3')
     sage: f.expand()
-    x^6*y^3+9*x^4*y^3+27*x^2*y^3+27*y^3+3*x^5*y^2+18*x^3*y^2+27*x*y^2+3*x^4*y+9*x^2*y+x^3
+    x^6*y^3 + 9*x^4*y^3 + 27*x^2*y^3 + 27*y^3 + 3*x^5*y^2 + 18*x^3*y^2 + 27*x*y^2 + 3*x^4*y + 9*x^2*y + x^3
     sage: f.subst('x=5/z')
-    (5/z+25*y/z^2+3*y)^3
+    (5/z + 25*y/z^2 + 3*y)^3
     sage: g = f.subst('x=5/z')
     sage: h = g.ratsimp(); h
-    (27*y^3*z^6+135*y^2*z^5+(675*y^3+225*y)*z^4+(2250*y^2+125)*z^3+(5625*y^3+1875*y)*z^2+9375*y^2*z+15625*y^3)/z^6
+    (27*y^3*z^6 + 135*y^2*z^5 + (675*y^3 + 225*y)*z^4 + (2250*y^2 + 125)*z^3 + (5625*y^3 + 1875*y)*z^2 + 9375*y^2*z + 15625*y^3)/z^6
     sage: h.factor()
-    (3*y*z^2+5*z+25*y)^3/z^6
+    (3*y*z^2 + 5*z + 25*y)^3/z^6
 
     sage: eqn = maxima(['a+b*c=1', 'b-a*c=0', 'a+b=5'])
     sage: s = eqn.solve('[a,b,c]'); s
-    [[a=(25*sqrt(79)*%i+25)/(6*sqrt(79)*%i-34),b=(5*sqrt(79)*%i+5)/(sqrt(79)*%i+11),c=(sqrt(79)*%i+1)/10],[a=(25*sqrt(79)*%i-25)/(6*sqrt(79)*%i+34),b=(5*sqrt(79)*%i-5)/(sqrt(79)*%i-11),c=-(sqrt(79)*%i-1)/10]]
+    [[a = (25*sqrt(79)*%i + 25)/(6*sqrt(79)*%i - 34),b = (5*sqrt(79)*%i + 5)/(sqrt(79)*%i + 11),c = (sqrt(79)*%i + 1)/10],[a = (25*sqrt(79)*%i - 25)/(6*sqrt(79)*%i + 34),b = (5*sqrt(79)*%i - 5)/(sqrt(79)*%i - 11),c =  - (sqrt(79)*%i - 1)/10]]
 
 Here is an example of solving an algebraic equation:
     sage: maxima('x^2+y^2=1').solve('y')
-    [y=-sqrt(1-x^2),y=sqrt(1-x^2)]
+    [y =  - sqrt(1 - x^2),y = sqrt(1 - x^2)]
     sage: maxima('x^2 + y^2 = (x^2 - y^2)/sqrt(x^2 + y^2)').solve('y')
-    [y=-sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2),y=sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2)]
+    [y =  - sqrt(( - y^2 - x^2)*sqrt(y^2 + x^2) + x^2),y = sqrt(( - y^2 - x^2)*sqrt(y^2 + x^2) + x^2)]
 
 You can even nicely typeset the solution in latex:
@@ -129,20 +137,20 @@
 
     sage: e = maxima('sin(u + v) * cos(u)^3'); e
-    cos(u)^3*sin(v+u)
+    cos(u)^3*sin(v + u)
     sage: f = e.trigexpand(); f
-    cos(u)^3*(cos(u)*sin(v)+sin(u)*cos(v))
+    cos(u)^3*(cos(u)*sin(v) + sin(u)*cos(v))
     sage: f.trigreduce()
-    (sin(v+4*u)+sin(v-2*u))/8+(3*sin(v+2*u)+3*sin(v))/8
+    (sin(v + 4*u) + sin(v - 2*u))/8 + (3*sin(v + 2*u) + 3*sin(v))/8
     sage: w = maxima('3 + k*%i')
     sage: f = w^2 + maxima('%e')^w
     sage: f.realpart()
-    %e^3*cos(k)-k^2+9
+    %e^3*cos(k) - k^2 + 9
     
     sage: f = maxima('x^3 * %e^(k*x) * sin(w*x)'); f
     x^3*%e^(k*x)*sin(w*x)
     sage: f.diff('x')
-    k*x^3*%e^(k*x)*sin(w*x)+3*x^2*%e^(k*x)*sin(w*x)+w*x^3*%e^(k*x)*cos(w*x)
+    k*x^3*%e^(k*x)*sin(w*x) + 3*x^2*%e^(k*x)*sin(w*x) + w*x^3*%e^(k*x)*cos(w*x)
     sage: f.integrate('x')
-    (((k*w^6+3*k^3*w^4+3*k^5*w^2+k^7)*x^3+(3*w^6+3*k^2*w^4-3*k^4*w^2-3*k^6)*x^2+(-18*k*w^4-12*k^3*w^2+6*k^5)*x-6*w^4+36*k^2*w^2-6*k^4)*%e^(k*x)*sin(w*x)+((-w^7-3*k^2*w^5-3*k^4*w^3-k^6*w)*x^3+(6*k*w^5+12*k^3*w^3+6*k^5*w)*x^2+(6*w^5-12*k^2*w^3-18*k^4*w)*x-24*k*w^3+24*k^3*w)*%e^(k*x)*cos(w*x))/(w^8+4*k^2*w^6+6*k^4*w^4+4*k^6*w^2+k^8)
+    (((k*w^6 + 3*k^3*w^4 + 3*k^5*w^2 + k^7)*x^3 + (3*w^6 + 3*k^2*w^4 - 3*k^4*w^2 - 3*k^6)*x^2 + ( - 18*k*w^4 - 12*k^3*w^2 + 6*k^5)*x - 6*w^4 + 36*k^2*w^2 - 6*k^4)*%e^(k*x)*sin(w*x) + (( - w^7 - 3*k^2*w^5 - 3*k^4*w^3 - k^6*w)*x^3 + (6*k*w^5 + 12*k^3*w^3 + 6*k^5*w)*x^2 + (6*w^5 - 12*k^2*w^3 - 18*k^4*w)*x - 24*k*w^3 + 24*k^3*w)*%e^(k*x)*cos(w*x))/(w^8 + 4*k^2*w^6 + 6*k^4*w^4 + 4*k^6*w^2 + k^8)
 
     sage: f = maxima('1/x^2')
@@ -151,8 +159,8 @@
     sage: g = maxima('f/sinh(k*x)^4')
     sage: g.taylor('x', 0, 3)
-    f/(k^4*x^4)-2*f/(3*k^2*x^2)+11*f/45-62*k^2*f*x^2/945
+    f/(k^4*x^4) - 2*f/(3*k^2*x^2) + 11*f/45 - 62*k^2*f*x^2/945
 
     sage: maxima.taylor('asin(x)','x',0, 10)
-    x+x^3/6+3*x^5/40+5*x^7/112+35*x^9/1152
+    x + x^3/6 + 3*x^5/40 + 5*x^7/112 + 35*x^9/1152
 
 \subsection{Examples involving matrices}
@@ -170,5 +178,5 @@
     [[0,4],[3,1]]
     sage: A.eigenvectors()
-    [[[0,4],[3,1]],[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3],[1,2,3,4]]
+    [[[0,4],[3,1]],[1,0,0, - 4],[0,1,0, - 2],[0,0,1, - 4/3],[1,2,3,4]]
 
 We can also compute the echelon form in \sage:
@@ -186,5 +194,5 @@
     sage: _ = maxima.eval("f(t) := t*sin(t)")
     sage: maxima("laplace(f(t),t,s)")
-    2*s/(s^2+1)^2
+    2*s/(s^2 + 1)^2
 
     sage: maxima("laplace(delta(t-3),t,s)") #Dirac delta function
@@ -193,10 +201,10 @@
     sage: _ = maxima.eval("f(t) := exp(t)*sin(t)")
     sage: maxima("laplace(f(t),t,s)")
-    1/(s^2-2*s+2)
+    1/(s^2 - 2*s + 2)
     
     sage: _ = maxima.eval("f(t) := t^5*exp(t)*sin(t)")
     sage: maxima("laplace(f(t),t,s)")
-    360*(2*s-2)/(s^2-2*s+2)^4-480*(2*s-2)^3/(s^2-2*s+2)^5+120*(2*s-2)^5/(s^2-2*s+2)^6
-    sage: print maxima("laplace(f(t),t,s)")
+    360*(2*s - 2)/(s^2 - 2*s + 2)^4 - 480*(2*s - 2)^3/(s^2 - 2*s + 2)^5 + 120*(2*s - 2)^5/(s^2 - 2*s + 2)^6
+    sage: maxima("laplace(f(t),t,s)").display2d()
                                              3                 5
                360 (2 s - 2)    480 (2 s - 2)     120 (2 s - 2)
@@ -206,11 +214,11 @@
 
     sage: maxima("laplace(diff(x(t),t),t,s)")
-    s*?%laplace(x(t),t,s)-x(0)
+    s*?%laplace(x(t),t,s) - x(0)
     
     sage: maxima("laplace(diff(x(t),t,2),t,s)")
-    -?%at('diff(x(t),t,1),t=0)+s^2*?%laplace(x(t),t,s)-x(0)*s
+    -?%at('diff(x(t),t,1),t = 0) + s^2*?%laplace(x(t),t,s) - x(0)*s
 
 It is difficult to read some of these without the 2d representation:
-    sage: print maxima("laplace(diff(x(t),t,2),t,s)")
+    sage.: maxima("laplace(diff(x(t),t,2),t,s)").display2d()
                          !
                 d        !         2
@@ -254,5 +262,5 @@
 
     sage: S = maxima('nusum(exp(1+2*i/n),i,1,n)')
-    sage: print S
+    sage.: S.display2d()
                             2/n + 3                   2/n + 1
                           %e                        %e
@@ -265,5 +273,5 @@
     sage: T = S*maxima('2/n')
     sage: T.tlimit('n','inf')
-    %e^3-%e
+    %e^3 - %e
 
 \subsection{Miscellaneous}
@@ -276,5 +284,5 @@
 Defining functions in maxima:
     sage: maxima.eval('fun[a] := a^2')
-    'fun[a]:=a^2'
+    'fun[a] := a^2'
     sage: maxima('fun[10]')
     100
@@ -290,8 +298,19 @@
 
 \subsection{Latex Output}
-To tex a maxima object do this:
+The latex output of Maxima is not perfect.  E.g.,
+
+    sage: maxima.eval('tex(sin(u) + sinh(v^2))')
+    '$$\\sinhv^2 + \\sinu$$false'
+    
+Notice the lack of space after the sin macro, which is a latex syntax
+error.  In \sage this is automatically fixed via a substition for
+trig functions, which may have potentially bad side effects:
 
     sage: latex(maxima('sin(u) + sinh(v^2)'))
     \sinh v^2+\sin u
+
+It would be nice if somebody would fix this problem.  One way would
+be to improve Maxima by making the fix to Maxima and giving this back
+to the Maxima people.
 
 Here's another example:
@@ -319,10 +338,4 @@
     sage: maxima(sin(x))
     sin(x)
-
-A long complicated input expression:
-
-    sage: maxima._eval_line('((((((((((0) + ((1) / ((n0) ^ (0)))) + ((1) / ((n1) ^ (1)))) + ((1) / ((n2) ^ (2)))) + ((1) / ((n3) ^ (3)))) + ((1) / ((n4) ^ (4)))) + ((1) / ((n5) ^ (5)))) + ((1) / ((n6) ^ (6)))) + ((1) / ((n7) ^ (7)))) + ((1) / ((n8) ^ (8)))) + ((1) / ((n9) ^ (9)));')
-    '1/n9^9+1/n8^8+1/n7^7+1/n6^6+1/n5^5+1/n4^4+1/n3^3+1/n2^2+1/n1+1'
-    
 """
 
@@ -349,11 +362,15 @@
 from pexpect import EOF
 
-import random
-
 import sage.rings.all
+#import sage.rings.complex_number2 as complex_number
 
 from sage.misc.misc import verbose, DOT_SAGE, SAGE_ROOT
 
 from sage.misc.multireplace import multiple_replace
+
+SAGE_START = '_s_start_'
+SAGE_END = '_s_stop_'
+cnt = 0
+seq = 0
 
 COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE
@@ -372,5 +389,8 @@
     def __call__(self, x):
         import sage.rings.all
-        return Expect.__call__(self, x)
+        if sage.rings.all.is_Infinite(x):
+            return Expect.__call__(self, 'inf')
+        else:
+            return Expect.__call__(self, x)
         
     def __init__(self, script_subdirectory=None, logfile=None, server=None):
@@ -380,14 +400,11 @@
         # TODO: Input and output prompts in maxima can be changed by
         # setting inchar and outchar..
-        eval_using_file_cutoff = 256
+        eval_using_file_cutoff = 200
         self.__eval_using_file_cutoff = eval_using_file_cutoff
-        STARTUP = '%s/local/bin/sage-maxima.lisp'%SAGE_ROOT
-        if not os.path.exists(STARTUP):
-            raise RuntimeError, 'You must get the file local/bin/sage-maxima.lisp'
         Expect.__init__(self,
                         name = 'maxima',
                         prompt = '\(\%i[0-9]+\)',
-                        command = 'maxima -p "%s"'%STARTUP, 
-                        maxread = 10000, 
+                        command = "maxima --disable-readline",
+                        maxread = 1,    # CRUCIAL to use less buffering for maxima (or get all kinds of hangs on OS X and 64-bit machines, etc!
                         script_subdirectory = script_subdirectory,
                         restart_on_ctrlc = False,
@@ -398,11 +415,5 @@
                         logfile = logfile,
                         eval_using_file_cutoff=eval_using_file_cutoff)
-        self._display_prompt = '<sage-display>'  # must match what is in the file local/ibn/sage-maxima.lisp!!
-        self._output_prompt_re = re.compile('\(\%o[0-9]+\)')
-        self._ask = ['zero or nonzero?', 'an integer?', 'positive, negative, or zero?', 'positive or negative?']
-        self._prompt_wait = [self._prompt] + [re.compile(x) for x in self._ask]
-        self._error_re = re.compile('(debugmode|Incorrect syntax|Maxima encountered a Lisp error)')
         self._display2d = False
-
 
     def __getattr__(self, attrname):
@@ -412,6 +423,28 @@
 
     def _start(self):
+        # For some reason sending a single input line at startup avoids
+        # lots of weird timing issues when doing doctests.
         Expect._start(self)
-        self._eval_line('0;')
+        self(1)    
+
+    # this doesn't work.
+    #def x_start(self):
+    #    Expect._start(self)
+    #    self._expect.sendline('inchar:"__SAGE__";')
+    #    self._change_prompt('__SAGE__[0-9]+\)')
+    #    self.expect().expect('__SAGE__[0-9]+\)')
+
+    def _eval_line_using_file(self, line, tmp):
+        F = open(tmp, 'w')
+        F.write(line)
+        F.close()
+        if self._expect is None:
+            self._start()
+        # For some reason this trivial comp
+        # keeps certain random freezes from occuring.  Do not remove this.
+        # The space before the \n is also important.
+        self._expect.sendline('0;batchload("%s"); \n'%tmp)
+        self._expect.expect(self._prompt)
+        return ''
 
     def __reduce__(self):
@@ -421,132 +454,82 @@
         return 'quit();'
 
-    def _sendline(self, str):
-        self._send(str)
-        os.write(self._expect.child_fd, os.linesep)
-
-    def _send(self, str):
+    def _eval_line(self, line, reformat=True, allow_use_file=False,
+                   wait_for_prompt=True):
+        if not wait_for_prompt:
+            return Expect._eval_line(self, line)
+        line = line.rstrip().rstrip(';')
+        if line == '':
+            return ''
+        global seq
+        seq += 1
+        start = SAGE_START + str(seq)
+        end = SAGE_END + str(seq)
+        line = '%s;\n%s; %s;'%(start, line, end)
         if self._expect is None:
             self._start()
-        os.write(self._expect.child_fd, str)
-
-    def _expect_expr(self, expr=None):
-        if expr is None:
-            expr = self._prompt_wait
-        if self._expect is None:
-            self._start()
+        if allow_use_file and self.__eval_using_file_cutoff and \
+                            len(line) > self.__eval_using_file_cutoff:
+            return self._eval_line_using_file(line, tmp)
         try:
-            i = self._expect.expect(expr)
-            if i > 0:
-                v = self._expect.before
-                j = v.find('Is ')
-                v = v[j:]
-                msg = "Computation failed since Maxima requested additional constraints (use assume):\n" + v + self._ask[i-1]
-                self._send(chr(3))
-                self._send(chr(3))
-                self._expect_expr()
-                raise ValueError, msg
-        except KeyboardInterrupt, msg:
-            #print self._expect.before
-            i = 0
-            while True:
-                try:
-                    print "Control-C pressed.  Interrupting Maxima. Please wait..."
-                    self._send('quit;\n'+chr(3))
-                    self._send('quit;\n'+chr(3))
-                    self.interrupt()
-                    self.interrupt()
-                except KeyboardInterrupt:
-                    i += 1
-                    if i > 10:
-                        break
-                    pass
-                else:
-                    break
-            raise KeyboardInterrupt, msg
-
-    def _interrupt(self):
-        self._send('quit;\n'+chr(3))
-        self._expect_expr()
-        self._send('quit;\n'+chr(3))
-        self._expect_expr()
-
-    def _before(self):
-        return self._expect.before
-
-    def _batch(self, str, batchload=True):
-        F = open(tmp, 'w')
-        F.write(str)
-        F.close()
-        if batchload:
-            cmd = 'batchload("%s");'%tmp
-        else:
-            cmd = 'batch("%s");'%tmp
-        self._sendline(cmd)
-        self._expect_expr()
-        out = self._before()
-        self._error_check(str, out)
-        return out
-
-    def _error_check(self, str, out):
-        r = self._error_re
-        m = r.search(out)
-        if not m is None:
-            self._error_msg(str, out)
-            
-    def _error_msg(self, str, out):
-        raise TypeError, "Error executing code in Maxima\nCODE:\n\t%s\nMaxima ERROR:\n\t%s"%(str, out)
-
-    def _eval_line(self, line, reformat=True, allow_use_file=False,
-                   wait_for_prompt=True):
-        if len(line) == 0:
+            E = self._expect
+            #print "in = '%s'"%line
+            E.sendline(line)
+            self._expect.expect(end)
+            # We have timeouts below, since getting the end above
+            # means the computation completed, but on some systems
+            # (Cygwin) the expect interface can sometimes hang getting
+            # the final prompts. 
+            try:
+                self._expect.expect(end, timeout=1)
+                out = self._expect.before
+                self._expect.expect(self._prompt, timeout=1)
+                out += self._expect.before
+            except pexpect.TIMEOUT:
+                out = self._expect.before
+            if not '(%o' in out:
+                self._expect.expect(self._prompt)
+
+        except EOF:
+            if self._quit_string() in line:
+                return ''
+        except KeyboardInterrupt:
+            self._keyboard_interrupt()
             return ''
-        line = line.rstrip()
-        if line[-1] != '$' and line[-1] != ';':
-            line += ';'
-            
-        self._synchronize()
-
-        if len(line) > self.__eval_using_file_cutoff:
-            a = self(line)
-            return repr(a)
-        else:
-            self._sendline(line)
-
-        if not wait_for_prompt:
-            return
-
-        self._expect_expr(self._display_prompt)
-        self._expect_expr()
-        out = self._before()
-        self._error_check(line, out)
-        
+
+        if 'Incorrect syntax:' in out:
+            raise RuntimeError, out
+
+        import os
+        if cygwin:
+            # for reasons I can't deduce yet, maxima behaves somewhat
+            # differently under cygwin...
+            out = out.lstrip(';')
+        else:
+	    i = out.rfind(start)
+	    j = out.rfind(end)
+            out = out[i+len(start):j]
+
         if not reformat:
             return out
-        
-        r = self._output_prompt_re
-        m = r.search(out)
-        if m is None:
-            o = out[:-2]
-        else:
-            o = out[m.end()+1:-2]
-        o = ''.join([x.strip() for x in o.split()])
-        return o
-
-        i = o.rfind('(%o')
-        return o[:i]
-
-
-    def _synchronize(self):
-        if self._expect is None: return
-        r = random.randrange(2147483647)
-        s = str(r+1)
-        cmd = "1+%s;\n"%r
-        self._send(cmd)
-        self._expect_expr()
-        if not s in self._before():
-            self._expect_expr(s)
-            self._expect_expr()
-
-            
+        if 'error' in out:
+            return out
+        out = out.lstrip()
+        i = out.find('(%o')
+        out0 = out[:i].strip()
+        i += out[i:].find(')')
+        out1 = out[i+1:].strip()
+        out = out0 + out1
+        out = ''.join(out.split())    # no whitespace
+        i = out.rfind(';;')
+        if i != -1:
+            out = out[i+2:]
+        out = out.replace('-', ' - ').replace('+',' + ').replace('=',' = ').replace(': =',' :=').replace('^ - ','^-')
+        if out[:3] == ' - ':
+            out = '-' + out[3:]
+        out = out.replace('E - ', 'E-')
+        out = out.replace('%e - ', '%e-')
+        i = out.rfind('(%o')
+        return out[:i]
+
 
     ###########################################
@@ -641,5 +624,5 @@
         return 'false'
 
-    def function(self, args, defn, rep=None, latex=None):
+    def function(self, args, defn, repr=None, latex=None):
         """
         Return the Maxima function with given arguments
@@ -650,5 +633,5 @@
             defn -- a string (or Maxima expression) that defines
                     a function of the arguments in Maxima.
-            rep  -- an optional string; if given, this is how the function will print.
+            repr -- an optional string; if given, this is how the function will print.
         
         EXAMPLES:
@@ -658,13 +641,12 @@
             sage: f = maxima.function('x,y', 'sin(x)+cos(y)')
             sage: f(2,3.5)
-            sin(2)-.9364566872907963
+            sin(2) - .9364566872907963
             sage: f
             sin(x)+cos(y)
             
-            sage: g = f.integrate('z')
-            sage: g
-            (cos(y)+sin(x))*z
+            sage: g = f.integrate('z'); g
+            (cos(y) + sin(x))*z
             sage: g(1,2,3)
-            3*(cos(2)+sin(1))
+            3*(cos(2) + sin(1))
 
         The function definition can be a maxima object:
@@ -674,24 +656,19 @@
             gamma(x)*sin(x)
             sage: t(2)
-             sin(2)
+            sin(2)
             sage: float(t(2))
             0.90929742682568171
             sage: loads(t.dumps())
             gamma(x)*sin(x)
+
+            
         """
         name = self._next_var_name()
-        if isinstance(defn, MaximaElement):
-            defn = defn.str()
-        elif not isinstance(defn, str):
-            defn = str(defn)
-        if isinstance(args, MaximaElement):
-            args = args.str()
-        elif not isinstance(args, str):
-            args = str(args)
-        cmd = '%s(%s) := %s'%(name, args, defn)
-        maxima._eval_line(cmd)
-        if rep is None:
-            rep = defn
-        f = MaximaFunction(self, name, rep, args, latex)
+        defn = str(defn)
+        args = str(args)
+        maxima.eval('%s(%s) := %s'%(name, args, defn))
+        if repr is None:
+            repr = defn
+        f = MaximaFunction(self, name, repr, args, latex)
         return f
 
@@ -699,20 +676,11 @@
         """
         Set the variable var to the given value.
-
-        INPUT:
-            var -- string
-            value -- string
-        """
-        if not isinstance(value, str):
-            raise TypeError
-        cmd = '%s : %s$'%(var, value.rstrip(';'))
-        if len(cmd) > self.__eval_using_file_cutoff:
-            self._batch(cmd, batchload=True)
-        else:
-            self._eval_line(cmd)
-            #self._sendline(cmd)
-            #self._expect_expr()
-            #out = self._before()
-            #self._error_check(cmd, out)
+        """
+        cmd = '%s : %s$"";'%(var, str(value).rstrip(';'))
+        out = self._eval_line(cmd, reformat=False, allow_use_file=True)
+        
+        if out.find("error") != -1:
+            raise TypeError, "Error executing code in Maxima\nCODE:\n\t%s\nMaxima ERROR:\n\t%s"%(cmd, out)
+
 
     def get(self, var):
@@ -720,15 +688,17 @@
         Get the string value of the variable var.
         """
-        s = self._eval_line('%s;'%var)
+        s = self._eval_line('%s'%var)
         return s
         
     def clear(self, var):
-        """
-        Clear the variable named var.
-        """
-        try:
-            self._eval_line('kill(%s)$'%var, reformat=False)
-        except TypeError:
-            pass
+         """
+         Clear the variable named var.
+         """
+         if self._expect is None:
+             return
+         try:
+             self._expect.sendline('kill(%s);\n'%var)
+         except:  # program around weirdness in pexpect
+             pass
         
     def console(self):
@@ -738,25 +708,25 @@
         return maxima_version()
 
-##     def display2d(self, flag=True):
-##         """
-##         Set the flag that determines whether Maxima objects are
-##         printed using their 2-d ASCII art representation.  When the
-##         maxima interface starts the default is that objects are not
-##         represented in 2-d.
-
-##         INPUT:
-##             flag -- bool (default: True)
-
-##         EXAMPLES
-##             sage: maxima('1/2')
-##             1/2
-##             sage: maxima.display2d(True)
-##             sage: maxima('1/2')
-##                                            1
-##                                            -
-##                                            2
-##             sage: maxima.display2d(False)
-##         """
-##         self._display2d = bool(flag)
+    def display2d(self, flag=True):
+        """
+        Set the flag that determines whether Maxima objects are
+        printed using their 2-d ASCII art representation.  When the
+        maxima interface starts the default is that objects are not
+        represented in 2-d.
+
+        INPUT:
+            flag -- bool (default: True)
+
+        EXAMPLES
+            sage: maxima('1/2')
+            1/2
+            sage: maxima.display2d(True)
+            sage: maxima('1/2')
+                                           1
+                                           -
+                                           2
+            sage: maxima.display2d(False)
+        """
+        self._display2d = bool(flag)
 
     def plot2d(self, *args):
@@ -890,12 +860,12 @@
                    
         EXAMPLES:
-            sage: maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'], [1,1,1])
-            y=3*x-2*%e^(x-1)
-            sage: maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'])
-            y=%k1*%e^x+%k2*%e^-x+3*x
-            sage: maxima.de_solve('diff(y,x) + 3*x = y', ['x','y'])
-            y=(%c-3*(-x-1)*%e^-x)*%e^x
-            sage: maxima.de_solve('diff(y,x) + 3*x = y', ['x','y'],[1,1])
-            y=-%e^-1*(5*%e^x-3*%e*x-3*%e)
+            sage.: maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'], [1,1,1])
+            y = 3*x - 2*%e^(x - 1)
+            sage.: maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'])
+            y = %k1*%e^x + %k2*%e^ - x + 3*x
+            sage.: maxima.de_solve('diff(y,x) + 3*x = y', ['x','y'])
+            y = (%c - 3*( - x - 1)*%e^ - x)*%e^x
+            sage.: maxima.de_solve('diff(y,x) + 3*x = y', ['x','y'],[1,1])
+            y =  - %e^ - 1*(5*%e^x - 3*%e*x - 3*%e)
         """
         if not isinstance(vars, str):
@@ -928,13 +898,13 @@
 
         EXAMPLES:
-            sage: maxima.clear('x'); maxima.clear('f')
-            sage: maxima.de_solve_laplace("diff(f(x),x,2) = 2*diff(f(x),x)-f(x)", ["x","f"], [0,1,2])
-            f(x)=x*%e^x+%e^x
+            sage.: maxima.clear('x'); maxima.clear('f')
+            sage.: maxima.de_solve_laplace("diff(f(x),x,2) = 2*diff(f(x),x)-f(x)", ["x","f"], [0,1,2])
+            f(x) = x*%e^x + %e^x
             
-            sage: maxima.clear('x'); maxima.clear('f')            
-            sage: f = maxima.de_solve_laplace("diff(f(x),x,2) = 2*diff(f(x),x)-f(x)", ["x","f"])
-            sage: f
-            f(x)=x*%e^x*(?%at('diff(f(x),x,1),x=0))-f(0)*x*%e^x+f(0)*%e^x
-            sage: print f
+            sage.: maxima.clear('x'); maxima.clear('f')            
+            sage.: f = maxima.de_solve_laplace("diff(f(x),x,2) = 2*diff(f(x),x)-f(x)", ["x","f"])
+            sage.: f
+            f(x) = x*%e^x*(at('diff(f(x),x,1),x = 0)) - f(0)*x*%e^x + f(0)*%e^x
+            sage.: f.display2d()
                                                !
                                    x  d        !                  x          x
@@ -969,6 +939,6 @@
             sage: eqns = ["x + z = y","2*a*x - y = 2*a^2","y - 2*z = 2"]    
             sage: vars = ["x","y","z"]                                      
-            sage: maxima.solve_linear(eqns, vars)
-            [x=a+1,y=2*a,z=a-1]
+            sage.: maxima.solve_linear(eqns, vars)                         
+            [x = a + 1,y = 2*a,z = a - 1]
         """
         eqs = "["
@@ -986,33 +956,33 @@
         return self('linsolve(%s, %s)'%(eqs, vrs))
 
-##     def unit_quadratic_integer(self, n):
-##         r"""
-##         Finds a unit of the ring of integers of the quadratic number
-##         field $\Q(\sqrt{n})$, $n>1$, using the qunit maxima command.
-
-##         EXAMPLE:
-##             sage: u = maxima.unit_quadratic_integer(101)           
-##             sage: u.parent()                                       
-##             Number Field in a with defining polynomial x^2 - 101
-##             sage: u                                                
-##             a + 10
-##             sage: u = maxima.unit_quadratic_integer(13)            
-##             sage: u                                                
-##             5*a + 18
-##             sage: u.parent()                                       
-##             Number Field in a with defining polynomial x^2 - 13
-##         """
-##         from sage.rings.all import QuadraticField, Integer
-##         # Take square-free part so sqrt(n) doesn't get simplified further by maxima
-##         # (The original version of this function would yield wrong answers if
-##         # n is not squarefree.)
-##         n = Integer(n).square_free_part()  
-##         if n < 1:
-##             raise ValueError, "n (=%s) must be >= 1"%n
-##         s = str(self('qunit(%s)'%n)).lower()
-##         r = re.compile('sqrt\(.*\)')
-##         s = r.sub('a', s)
-##         a = QuadraticField(n, 'a').gen()
-##         return eval(s)
+    def unit_quadratic_integer(self, n):
+        r"""
+        Finds a unit of the ring of integers of the quadratic number
+        field $\Q(\sqrt{n})$, $n>1$, using the qunit maxima command.
+
+        EXAMPLE:
+            sage: u = maxima.unit_quadratic_integer(101)           
+            sage: u.parent()                                       
+            Number Field in a with defining polynomial x^2 - 101
+            sage: u                                                
+            a + 10
+            sage: u = maxima.unit_quadratic_integer(13)            
+            sage: u                                                
+            5*a + 18
+            sage: u.parent()                                       
+            Number Field in a with defining polynomial x^2 - 13
+        """
+        from sage.rings.all import QuadraticField, Integer
+        # Take square-free part so sqrt(n) doesn't get simplified further by maxima
+        # (The original version of this function would yield wrong answers if
+        # n is not squarefree.)
+        n = Integer(n).square_free_part()  
+        if n < 1:
+            raise ValueError, "n (=%s) must be >= 1"%n
+        s = str(self('qunit(%s)'%n)).lower()
+        r = re.compile('sqrt\(.*\)')
+        s = r.sub('a', s)
+        a = QuadraticField(n, 'a').gen()
+        return eval(s)
 
     def plot_list(self, ptsx, ptsy, options=None):
@@ -1033,6 +1003,6 @@
 
         EXAMPLES:
-            sage: zeta_ptsx = [ (pari(1/2 + i*I/10).zeta().real()).precision(1) for i in range (70,150)]  
-            sage: zeta_ptsy = [ (pari(1/2 + i*I/10).zeta().imag()).precision(1) for i in range (70,150)]  
+            sage.: zeta_ptsx = [ (pari(1/2 + i*I/10).zeta().real()).precision(1) for i in range (70,150)]  
+            sage.: zeta_ptsy = [ (pari(1/2 + i*I/10).zeta().imag()).precision(1) for i in range (70,150)]  
             sage.: maxima.plot_list(zeta_ptsx, zeta_ptsy)                   
             sage.: opts='[gnuplot_preamble, "set nokey"], [gnuplot_term, ps], [gnuplot_out_file, "zeta.eps"]'
@@ -1092,20 +1062,4 @@
         return P('%s(%s)'%(self.name(), x))
     
-    def __str__(self):
-        """
-        Printing an object explicitly gives ASCII art:
-
-        EXAMPLES:
-            sage: f = maxima('1/(x-1)^3'); f
-            1/(x-1)^3
-            sage: print f
-                                                  1
-                                               --------
-                                                      3
-                                               (x - 1)
-
-        """
-        return self.display2d(onscreen=False)
-
     def __cmp__(self, other):
         """
@@ -1131,21 +1085,13 @@
         # thanks to David Joyner for telling me about using "is".
         P = self.parent()
-        try:
-            if P.eval("is (%s < %s)"%(self.name(), other.name())) == P._true_symbol():
-                return -1
-            elif P.eval("is (%s > %s)"%(self.name(), other.name())) == P._true_symbol():
-                return 1
-            elif P.eval("is (%s = %s)"%(self.name(), other.name())) == P._true_symbol():
-                return 0
-        except TypeError:
-            pass
-        return cmp(repr(self),repr(other))
-                   # everything is supposed to be comparable in Python, so we define
-                   # the comparison thus when no comparable in interfaced system.
-
-    def sage_object(self):
-         from sage.calculus.calculus import symbolic_expression_from_maxima_string
-         return symbolic_expression_from_maxima_string(self.name(), maxima=self.parent())
-
+        if P.eval("is (%s < %s)"%(self.name(), other.name())) == P._true_symbol():
+            return -1
+        elif P.eval("is (%s > %s)"%(self.name(), other.name())) == P._true_symbol():
+            return 1
+        elif P.eval("is (%s = %s)"%(self.name(), other.name())) == P._true_symbol():
+            return 0
+        else:
+            return -1  # everything is supposed to be comparable in Python, so we define
+                       # the comparison thus when no comparable in interfaced system.
     def numer(self):
         return self.comma('numer')
@@ -1170,16 +1116,15 @@
 
     def str(self):
-        P = self._check_valid()
+        self._check_valid()
+        P = self.parent()
         return P.get(self._name)
 
     def __repr__(self):
-        try:
-            return self.__repr
-        except AttributeError:
-            pass
-        P = self._check_valid()
-        r = P.get(self._name)
-        self.__repr = r
-        return r
+        self._check_valid()
+        P = self.parent()
+        if P._display2d:
+            return self.display2d(onscreen=False)
+        else:
+            return P.get(self._name)
 
     def display2d(self, onscreen=True):
@@ -1194,17 +1139,17 @@
         P = self.parent()
         s = P._eval_line('display2d : true; %s'%self.name(), reformat=False)
-        P._eval_line('display2d : false;', reformat=False)
-
-        r = P._output_prompt_re
-
-        m = r.search(s)
-        s = s[m.start():]
-        i = s.find('\n')
-        s = s[i+1 + len(P._display_prompt):]
-        m = r.search(s)
-        if not m is None:
-            s = s[:m.start()] + ' '*(m.end() - m.start()) + s[m.end():].rstrip()
-        # if ever want to dedent, see
-        # http://mail.python.org/pipermail/python-list/2006-December/420033.html
+        P._eval_line('display2d : false', reformat=False)
+        if not cygwin:
+            i = s.find('true')
+            i += s[i:].find('\n')
+            s = s[i+1:]
+        i = s.find('true')
+        i += s[i:].find('\n')
+        j = s.rfind('(%o')
+        s = s[i:j-2]
+        i = s.find('(%o')
+        j = i + s[i:].find(')')
+        s = s[:i] + ' '*(j-i+1) + s[j+1:]
+        s = s.lstrip('\n')
         if onscreen:
             print s
@@ -1231,10 +1176,10 @@
             sage: f.diff('x', 2)                             
             2
-            sage: maxima('sin(x^2)').diff('x',4)
-            16*x^4*sin(x^2)-12*sin(x^2)-48*x^2*cos(x^2)
+            sage: maxima('sin(x^2)').diff('x',4)             
+            16*x^4*sin(x^2) - 12*sin(x^2) - 48*x^2*cos(x^2)  
 
             sage: f = maxima('x^2 + 17*y^2')                 
             sage: f.diff('x')
-            34*y*'diff(y,x,1)+2*x
+            2*x
             sage: f.diff('y')                                
             34*y
@@ -1305,12 +1250,12 @@
         EXAMPLES:
             sage: maxima('x^2+1').integral()                   
-            x^3/3+x
+            x^3/3 + x
             sage: maxima('x^2+ 1 + y^2').integral('y')         
-            y^3/3+x^2*y+y
+            y^3/3 + x^2*y + y
             sage: maxima('x / (x^2+1)').integral()             
-            log(x^2+1)/2
+            log(x^2 + 1)/2
             sage: maxima('1/(x^2+1)').integral()               
             atan(x)
-            sage: maxima('1/(x^2+1)').integral('x', 0, infinity) 
+            sage.: maxima('1/(x^2+1)').integral('x', 0, infinity) 
             %pi/2
             sage: maxima('x/(x^2+1)').integral('x', -1, 1)     
@@ -1336,8 +1281,5 @@
 
     def __float__(self):
-        try:
-            return float(str(self.numer()))
-        except ValueError:
-            raise TypeError, "unable to coerce '%s' to float"%repr(self)
+        return float(str(self.numer()))
 
     def __len__(self):
@@ -1393,5 +1335,5 @@
         self._check_valid()
         P = self.parent()
-        s = P._eval_line('tex(%s);'%self.name(), reformat=False)
+        s = maxima._eval_line('tex(%s)'%self.name(), reformat=False)
         if not '$$' in s:
             raise RuntimeError, "Error texing maxima object."
@@ -1467,6 +1409,6 @@
             sage: f = maxima('1/((1+x)*(x-1))')            
             sage: f.partial_fraction_decomposition('x')    
-            1/(2*(x-1))-1/(2*(x+1))
-            sage: print f.partial_fraction_decomposition('x')
+            1/(2*(x - 1)) - 1/(2*(x + 1))
+            sage: f.partial_fraction_decomposition('x').display2d() 
                                  1           1
                              --------- - ---------
@@ -1492,7 +1434,4 @@
         self.__args = args
         self.__latex = latex
-
-    def __reduce__(self):
-        return reduce_load_Maxima_function, (self.parent(), self.__defn, self.__args, self.__latex)
         
     def __call__(self, *x):
@@ -1523,5 +1462,5 @@
         else:
             args = self.__args + ',' + var
-        return P.function(args, repr(f))
+        return P.function(args, str(f))
 
 
@@ -1534,8 +1473,4 @@
 def reduce_load_Maxima():
     return maxima
-
-def reduce_load_Maxima_function(parent, defn, args, latex):
-    return parent.function(args, defn, defn, latex)
-    
 
 import os
@@ -1549,4 +1484,2 @@
     import sage.interfaces.quit
     sage.interfaces.quit.expect_quitall()
-
-
Index: age/interfaces/mupad.py
===================================================================
--- sage/interfaces/mupad.py	(revision 3692)
+++ 	(revision )
@@ -1,233 +1,0 @@
-r"""
-Interface to MuPAD
-
-AUTHOR:
-    -- William Stein 
-
-You must have the optional commercial MuPAD interpreter installed and
-available as the command \code{mupkern} in your PATH in order to use
-this interface.  You do not have to install any optional \sage
-packages.
-"""
-
-#############################################################################
-#       Copyright (C) 2007 William Stein <wstein@gmail.com>
-#
-#  Distributed under the terms of the GNU General Public License (GPL)
-#
-#                  http://www.gnu.org/licenses/
-#############################################################################
-
-seq = 0
-PROMPT = '___SAGE___'
-
-import os
-
-from expect import (Expect, ExpectElement, ExpectFunction,
-                    FunctionElement, AsciiArtString)
-
-import pexpect
-
-from sage.misc.misc import verbose, DOT_SAGE
-from sage.misc.pager import pager
-
-class Mupad(Expect):
-    """
-    Interface to the MuPAD interpreter.
-    """
-    def __init__(self, maxread=1000, script_subdirectory="", logfile=None):
-        """
-        Create an instance of the MuPAD interpreter.        
-        """
-        Expect.__init__(self,
-                        name = 'MuPAD',
-                        prompt = '>>',
-                        command = "mupkern -P e",
-                        maxread = maxread,
-                        script_subdirectory = script_subdirectory,
-                        restart_on_ctrlc = False,
-                        verbose_start = False,
-                        logfile = logfile)
-    
-    def __getattr__(self, attrname):
-        if attrname[:1] == "_":
-            raise AttributeError
-        return MupadFunction(self, attrname)
-
-    def _keyboard_interrupt(self):
-        print "Interrupting %s..."%self
-        self._expect.sendline(chr(3))  # send ctrl-c
-        self._expect.expect(PROMPT)
-        self._expect.expect(PROMPT)
-        raise RuntimeError, "Ctrl-c pressed while running %s"%self
-
-    def __reduce__(self):
-        return reduce_load_mupad, tuple([])
-
-    def _read_in_file_command(self, filename):
-        return 'read "%s"'%filename
-
-    def _start(self, alt_message=None, block_during_init=True):
-        Expect._start(self, alt_message=alt_message, block_during_init=block_during_init)
-        self._expect.sendline('Pref::promptString("%s");'%PROMPT)
-        self._expect.expect(PROMPT)
-        self._expect.send('1;')
-        self._expect.expect(PROMPT)        
-        
-    def _quit_string(self):
-        return 'quit'
-
-    def _install_hints(self):
-        """
-        Hints for installing MuPAD on your computer.
-        """
-        return """
-In order to use the MuPAD interface you need to have MuPAD installed
-and have a script in your PATH called "mupkern" that runs the
-command-line version of MuPAD. 
-
-  (1) You might have to buy MuPAD.
-      
-  (2) * LINUX: The mupkern script comes standard with your Mupad install.
-        
-      * APPLE OS X:
-         ???
-"""
-
-    def expect(self):
-        return self._expect
-
-    def console(self):
-        mupad_console()
-
-    def eval(self, code, strip=True):
-        s = Expect.eval(self, code)
-        return AsciiArtString(s)
-
-    def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True,
-                   need_output=True):
-        if self._expect is None:
-            self._start()
-        if not need_output:
-            E = self._expect
-            E.sendline(line)
-            return
-        
-        global seq
-        seq += 1
-        START = '__start__(%s+1)'%seq
-        END = '__end__(%s+1)'%seq
-        line = '%s; %s; %s;'%(START, line, END)
-        START = '__start__(%s)'%(seq+1)
-        END = '__end__(%s)'%(seq+1)
-        
-        E = self._expect
-        E.sendline(line)
-        E.expect(PROMPT)
-        z = E.before
-        i = z.find(START)
-        if i == -1:
-            raise RuntimeError, "%s\nError evaluating code in MuPAD"%z
-        z = z[i+len(START)+2:]
-        z = z.rstrip().rstrip(END).rstrip('"').rstrip().strip('\n').strip('\r').strip('\n').replace('\\\r\n','')
-        i = z.find('Error: ')
-        if i != -1:
-            raise RuntimeError, z[i + 7:]
-        return z
-
-    def cputime(self, t=None):
-        if t is None:
-            return float(self('time()'))
-        else:
-            return float(self('time() - %s'%float(t)))
-
-    def set(self, var, value):
-        """
-        Set the variable var to the given value.
-        """
-        cmd = '%s:=%s:'%(var,value)
-        out = self.eval(cmd)
-        i = out.find('Error: ')
-        if i != -1:
-            raise RuntimeError, out[i + 7:]
-
-    def get(self, var):
-        """
-        Get the value of the variable var.
-        """
-        s = self.eval('%s'%var)
-        i = s.find('=')
-        return s[i+1:]
-
-    def get_using_file(self, var):
-        """
-        Get the value of the variable var using a file.
-
-        (I would make this the default for values that are bigger than
-        a few thousand characters.  However, it's not at all obvious
-        how to figure out if the string representation of an object is
-        big ahead of time!  We assume it is for now, if the string
-        used to create the object was big.)
-        """
-        s = self.eval('save %s, "%s"'%(var, tmp))
-        s = open(tmp).read().replace('\\\n','')
-        i = s.find('=')
-        return s[i+2:-2]
-    
-    def _object_class(self):
-        return MupadElement
-
-    def _equality_symbol(self):
-        return '=='
-
-    def _assign_symbol(self):
-        return ":="
-
-    def _help(self, str):
-        return os.popen('echo "?%s" | mupad -q'%str).read()
-
-class MupadFunction(ExpectFunction):
-    def _sage_doc_(self):
-        M = self._parent
-        return M._help(self._name)
-
-class MupadFunctionElement(FunctionElement):
-    def _sage_doc_(self):
-        return self._obj.parent()._help(self._name)
-    
-
-class MupadElement(ExpectElement):
-    def __getattr__(self, attrname):
-        if attrname[:1] == "_":
-            raise AttributeError
-        return MupadFunctionElement(self, attrname)
-
-    def trait_names(self):
-        return self.parent().trait_names()
-
-    def __repr__(self):
-        self._check_valid()
-        return self.parent().get(self._name)
-
-    def _latex_(self):
-        self._check_valid()
-        P = self.parent()
-        s = P._eval_line('generate::TeX(%s)'%self.name())
-        s = s.replace('\\\\','\\').strip().strip('"')
-        return s
-
-# An instance
-mupad = Mupad(script_subdirectory='user')
-
-def reduce_load_mupad():
-    return mupad
-
-import os
-def mupad_console():
-    os.system('mupkern')
-
-
-def __doctest_cleanup():
-    import sage.interfaces.quit
-    sage.interfaces.quit.expect_quitall()
-
Index: sage/interfaces/mwrank.py
===================================================================
--- sage/interfaces/mwrank.py	(revision 4062)
+++ sage/interfaces/mwrank.py	(revision 1097)
@@ -68,5 +68,5 @@
 
     def __call__(self, cmd):
-        return self.eval(str(cmd))
+        return self.eval(cmd)
 
     def console(self):
Index: sage/interfaces/quit.py
===================================================================
--- sage/interfaces/quit.py	(revision 4022)
+++ sage/interfaces/quit.py	(revision 2920)
@@ -1,5 +1,5 @@
 """nodoctest"""
 
-import os, time, pexpect
+import os, time
 
 expect_objects = []
@@ -11,7 +11,7 @@
             try:
                 R.quit(verbose=verbose)
-                pass
-            except RuntimeError:
-                pass
+            except RuntimeError, msg:
+                if verbose:
+                    print msg
     kill_spawned_jobs()
 
@@ -24,12 +24,18 @@
         pid = L[:i].strip()
         cmd = L[i+1:].strip()
-        try:
-            #s = "Killing spawned job %s"%pid
-            #if len(cmd) > 0:
-            #    s += ' (%s)'%cmd
-            #print s
-            os.killpg(int(pid), 9)
-        except:
-            pass
+        j = 0
+        while j < 3:
+            j += 1
+            if not is_running(pid):
+                break
+            try:
+                os.killpg(int(pid), 9)
+            except OSError, msg:
+                pass
+            else:
+                j += 1
+                if j > 5:
+                    os.kill(int(pid), 9)
+                    break
             
 def is_running(pid):
Index: sage/interfaces/singular.py
===================================================================
--- sage/interfaces/singular.py	(revision 4059)
+++ sage/interfaces/singular.py	(revision 3036)
@@ -794,7 +794,7 @@
             P.eval('%s[%s] = %s'%(self.name(), n, value.name()))
 
-    def __nonzero__(self):
+    def is_zero(self):
         P = self.parent()
-        return P.eval('%s == 0'%self.name()) == '0'
+        return P.eval('%s == 0'%self.name()) == '1'
             
     def sage_polystring(self):
Index: sage/lfunctions/dokchitser.py
===================================================================
--- sage/lfunctions/dokchitser.py	(revision 3709)
+++ sage/lfunctions/dokchitser.py	(revision 3290)
@@ -278,17 +278,13 @@
         s = s.replace('.E','.0E').replace(' ','')
         return self.__CC(sage_eval(s, locals={'I':self.__CC.gen(0)}))
-
-    def _clear_value_cache(self):
-        del self.__values
+        
 
     def __call__(self, s, c=None):
-        r"""
+        """
         INPUT:
             s -- complex number
-
-        NOTE: Evaluation of the function takes a long time, so each
-              evaluation is cached.  Call \code{self._clear_value_cache()}
-              to clear the evaluation cache.
-        
+            c -- (optional); cutoff which should be a real number > 1
+                 that is chosen close to 1.
+
         EXAMPLES:
             sage: E = EllipticCurve('5077a')
@@ -301,10 +297,4 @@
         self.__check_init()
         s = self.__CC(s)
-        try:
-            return self.__values[s]
-        except AttributeError:
-            self.__values = {}
-        except KeyError:
-            pass
         z = self.gp().eval('L(%s)'%s)
         if 'pole' in z:
@@ -316,10 +306,6 @@
             msg = z[:i].replace('digits','decimal digits')
             verbose(msg, level=-1)
-            ans = self.__to_CC(z[i+1:])
-            self.__values[s] = ans
-            return ans
-        ans = self.__to_CC(z)
-        self.__values[s] = ans
-        return ans
+            return self.__to_CC(z[i+1:])
+        return self.__to_CC(z)
         
     def derivative(self, s, k=1):
Index: sage/libs/cf/cf.pyxe
===================================================================
--- sage/libs/cf/cf.pyxe	(revision 4059)
+++ sage/libs/cf/cf.pyxe	(revision 2755)
@@ -873,11 +873,13 @@
         return bool(CF_isOne(self.thisptr))
 
-    def __nonzero__(CanonicalForm self):
-        """
-        This predicate returns true if self does not represent the zero
-        element of the current base domain. 
+    def is_zero(CanonicalForm self):
+        """
+        This predicate returns true if self represents the zero
+        element of the current base domain. Like the predicate is_one
+        using the predicate f.is_zero() is also faster than a
+        comparison via f == 0.
         """
         #embed{ int CF_isZero(void *e)
-        return not ((CanonicalForm*)e)->isZero();
+        return ((CanonicalForm*)e)->isZero();
         #}embed
 
Index: sage/libs/m4ri/packedmatrix.c
===================================================================
--- sage/libs/m4ri/packedmatrix.c	(revision 3932)
+++ sage/libs/m4ri/packedmatrix.c	(revision 3498)
@@ -356,10 +356,10 @@
 int gaussianPackedDelayed(packedmatrix *m, int startcol, int full) {
   int i,j;
-  int start; 
+  int start, stop=min( m->rows, m->cols);
 
   int startrow = startcol;
   int ii;
   int pivots = 0;
-  for (i=startcol ; i<m->cols ; i++) {
+  for (i=startcol ; i<stop ; i++) {
 
     for(j=startrow ; j < m->rows; j++) {
Index: sage/matrix/constructor.py
===================================================================
--- sage/matrix/constructor.py	(revision 3973)
+++ sage/matrix/constructor.py	(revision 3187)
@@ -72,5 +72,4 @@
        ring for all the entries (using the Sequence object):
 
-        sage: x = polygen(QQ)
         sage: m = matrix([[1/3,2+x],[3,4]]); m
         [  1/3 x + 2]
Index: sage/matrix/matrix0.pyx
===================================================================
--- sage/matrix/matrix0.pyx	(revision 4022)
+++ sage/matrix/matrix0.pyx	(revision 3543)
@@ -717,5 +717,5 @@
         S = []
         for x in self.list():
-            S.append(repr(x))
+            S.append(str(x))
 
         tmp = []
Index: sage/matrix/matrix1.pyx
===================================================================
--- sage/matrix/matrix1.pyx	(revision 4062)
+++ sage/matrix/matrix1.pyx	(revision 3477)
@@ -82,5 +82,5 @@
             matrix([0,1,2],[3,4,5],[6,7,8])
             sage: a.charpoly('x').expand()
-            -x^3+12*x^2+18*x
+            -x^3 + 12*x^2 + 18*x
             sage: m.charpoly()
             x^3 - 12*x^2 - 18*x
Index: sage/matrix/matrix2.pyx
===================================================================
--- sage/matrix/matrix2.pyx	(revision 4022)
+++ sage/matrix/matrix2.pyx	(revision 3665)
@@ -390,5 +390,5 @@
         # TODO: find reasonable cutoff (Field specific, but seems to be quite large for Q[x])
         # if R.is_integral_domain() and R.is_exact() and algorithm == "hessenberg":
-        if  R.is_field() and R.is_exact() and algorithm == "hessenberg":
+        if  R.is_field() and algorithm == "hessenberg":
             c = self.charpoly('x')[0]
             if self._nrows % 2:
@@ -2093,5 +2093,5 @@
             if PyErr_CheckSignals(): raise KeyboardInterrupt
             for r from start_row <= r < nr:
-                if A.get_unsafe(r, c):
+                if A.get_unsafe(r, c) != 0:
                     pivots.append(c)
                     a_inverse = ~A.get_unsafe(r,c)
@@ -2100,5 +2100,5 @@
                     for i from 0 <= i < nr:
                         if i != start_row:
-                            if A.get_unsafe(i,c):
+                            if A.get_unsafe(i,c) != 0:
                                 minus_b = -A.get_unsafe(i, c)
                                 A.add_multiple_of_row(i, start_row, minus_b, c)
Index: sage/matrix/matrix_complex_double_dense.pyx
===================================================================
--- sage/matrix/matrix_complex_double_dense.pyx	(revision 4062)
+++ sage/matrix/matrix_complex_double_dense.pyx	(revision 3616)
@@ -328,5 +328,4 @@
              
         EXAMPLES:
-            sage: I = CDF.gen()
             sage: m = I*Matrix(CDF, 3, range(9))
             sage: vals, vecs = m.eigen_left()
@@ -358,5 +357,5 @@
 
         EXAMPLES:
-            sage: m = CDF.gen() * matrix(CDF, 3, range(9))       
+            sage: m = I*Matrix(CDF, 3, range(9))       
             sage: vals, vecs = m.eigen()
             sage: vecs*m                 # random lower order precision
@@ -428,5 +427,4 @@
         
         EXAMPLES:
-            sage: I = CDF.gen()
             sage: A =I*matrix(CDF, 3,3, [1,2,5,7.6,2.3,1,1,2,-1])
             sage: A   # slightly random output
@@ -473,6 +471,5 @@
         
         EXAMPLES:
-            sage: I = CDF.gen()
-            sage: A = I*matrix(CDF, 3,3, [1,2,5,7.6,2.3,1,1,2,-1])
+            sage: A =I*matrix(CDF, 3,3, [1,2,5,7.6,2.3,1,1,2,-1])
             sage: A   # slightly random output
             [1.0*I             2.0*I                5.0*I]
@@ -547,5 +544,5 @@
             [  0 1.0]
             [2.0 3.0]
-            sage: RDF(log(abs(m.determinant())))
+            sage: log(abs(m.determinant()))
             0.69314718056
             sage: m.log_determinant()
@@ -654,5 +651,4 @@
 
         EXAMPLES:
-            sage: I = CDF.gen()
             sage: m = matrix(CDF,[[1,2],[3,4]])
             sage: m = I*m
Index: sage/matrix/matrix_integer_dense.pyx
===================================================================
--- sage/matrix/matrix_integer_dense.pyx	(revision 4059)
+++ sage/matrix/matrix_integer_dense.pyx	(revision 3665)
@@ -497,5 +497,5 @@
     # def _dict(self):
 
-    def __nonzero__(self):
+    def is_zero(self):
         cdef mpz_t *a, *b
         cdef Py_ssize_t i, j
@@ -503,6 +503,6 @@
         for i from 0 <= i < self._nrows * self._ncols:
             if mpz_cmp_si(self._entries[i], 0):
-                return True
-        return False
+                return False
+        return True
 
     def _multiply_linbox(self, Matrix right):
Index: sage/matrix/matrix_mod2_dense.pyx
===================================================================
--- sage/matrix/matrix_mod2_dense.pyx	(revision 3931)
+++ sage/matrix/matrix_mod2_dense.pyx	(revision 3506)
@@ -58,31 +58,4 @@
     [0 1 0]
 
-TESTS:
-    sage: FF = FiniteField(2)
-    sage: V = VectorSpace(FF,2)
-    sage: v = V([0,1]); v
-    (0, 1)
-    sage: W = V.subspace([v])
-    sage: W
-    Vector space of degree 2 and dimension 1 over Finite Field of size 2
-    Basis matrix:
-    [0 1]
-    sage: v in W
-    True
-
-    sage: M = Matrix(GF(2), [[1,1,0],[0,1,0]])
-    sage: M.row_space()
-    Vector space of degree 3 and dimension 2 over Finite Field of size 2
-    Basis matrix:
-    [1 0 0]
-    [0 1 0]
-
-    sage: M = Matrix(GF(2), [[1,1,0],[0,0,1]])
-    sage: M.row_space()
-    Vector space of degree 3 and dimension 2 over Finite Field of size 2
-    Basis matrix:
-    [1 1 0]
-    [0 0 1]
-
 TODO:
    - make linbox frontend and use it
@@ -311,7 +284,4 @@
         cdef int n = self._ncols
         cdef int k = round(min(0.75 * log(n,2), 16))
-
-        if k < 1:
-            k = 1
 
 ##         if ( self.nrows() < right.ncols() ): 
@@ -615,12 +585,4 @@
              True
 
-        TESTS:
-             sage: VF2 = VectorSpace(GF(2),2)
-             sage: WF2 = VF2.submodule([VF2([1,1])])
-             sage: WF2
-             Vector space of degree 2 and dimension 1 over Finite Field of size 2
-             Basis matrix:
-             [1 1]
-
         ALGORITHM: Uses Gregory Bard's M4RI algorithm and implementation or
                    LinBox.
@@ -649,11 +611,9 @@
                 n = min(self._nrows, self._ncols)
                 k = round(min(0.75 * log(n,2), 16))
-                if k<1:
-                    k = 1
 
             _sig_on
             r =  simpleFourRussiansPackedFlex(self._entries, 1, k)
             _sig_off
-            
+
             self.cache('in_echelon_form',True)
             self.cache('rank', r)
Index: sage/matrix/matrix_real_double_dense.pyx
===================================================================
--- sage/matrix/matrix_real_double_dense.pyx	(revision 4003)
+++ sage/matrix/matrix_real_double_dense.pyx	(revision 3616)
@@ -555,5 +555,5 @@
             [0.0 1.0]
             [2.0 3.0]
-            sage: RDF(log(abs(m.determinant())))
+            sage: log(abs(m.determinant()))
             0.69314718056
             sage: m.log_determinant()
Index: sage/matrix/solve.pyx
===================================================================
--- sage/matrix/solve.pyx	(revision 3751)
+++ sage/matrix/solve.pyx	(revision 3385)
@@ -67,5 +67,4 @@
               z=gsl_vector_complex_get(result_vector,i)
               list.append(sage.rings.complex_double.CDF(GSL_REAL(z),GSL_IMAG(z)))
-    #          list.append(gsl_vector_complex_get(result_vector, i))
        gsl_vector_complex_free(result_vector)
        return vector(sage.rings.complex_double.CDF,list) #todo: don't go through python
Index: sage/misc/all.py
===================================================================
--- sage/misc/all.py	(revision 4063)
+++ sage/misc/all.py	(revision 3610)
@@ -30,6 +30,4 @@
 from sagedoc import search_src, search_doc
 
-from reset import reset, restore
-
 from getusage import top, get_memory_usage
 
@@ -50,73 +48,10 @@
 from func_persist import func_persist
 
-from functional import (additive_order,
-                        sqrt as numerical_sqrt,
-                        arg,
-                        base_ring,
-                        base_field,
-                        basis,
-                        category,
-                        charpoly,
-                        coerce,
-                        cyclotomic_polynomial,
-                        decomposition,
-                        denominator,
-                        derivative,
-                        det,
-                        dimension,
-                        dim,
-                        discriminant,
-                        disc,
-                        eta,
-                        exp,
-                        factor,
-                        fcp,
-                        gens,
-                        hecke_operator,
-                        ideal,
-                        image,
-                        imag,
-                        imaginary,
-                        integral,
-                        integral_closure,
-                        interval,
-                        xinterval,
-                        is_commutative,
-                        is_even,
-                        is_integrally_closed,
-                        is_field,
-                        is_odd,
-                        kernel,
-                        krull_dimension,
-                        lift,
-                        minimal_polynomial,
-                        multiplicative_order,
-                        ngens,
-                        norm,
-                        numerator,
-                        objgens,
-                        objgen,
-                        one,
-                        order,
-                        rank,
-                        real,
-                        regulator,
-                        round,
-                        quotient,
-                        quo,
-                        show,
-                        isqrt,
-                        square_free_part,
-                        squarefree_part,
-                        transpose,
-                        zero,
-                        log as log_b,
-                        parent)
-
+from functional import *
 
 from latex import latex, view, lprint, jsmath
  
 # disabled -- nobody uses mathml
-#from mathml ml
+#from mathml import mathml
 
 from trace import trace
Index: sage/misc/functional.py
===================================================================
--- sage/misc/functional.py	(revision 4063)
+++ sage/misc/functional.py	(revision 3290)
@@ -52,7 +52,7 @@
 
     EXAMPLES:
-        sage: z = CC(1,2)
+        sage: z = 1+2*I
         sage: theta = arg(z)
-        sage: cos(theta)*abs(z)   
+        sage: cos(theta)*abs(z)   # slightly random output on cygwin
         1.00000000000000
         sage: sin(theta)*abs(z)
@@ -146,4 +146,9 @@
     Return the arc cosine of x.
 
+    EXAMPLES:
+        sage: acos(0.5)
+        1.04719755119660
+        sage: acos(1 + I*1.0)
+        0.904556894302381 - 1.06127506190504*I
     """
     try: return x.acos()
@@ -154,4 +159,9 @@
     Return the arc sine of x.
 
+    EXAMPLES:
+        sage: asin(0.5)
+        0.523598775598299
+        sage: asin(1 + I*1.0)
+        0.666239432492515 + 1.06127506190504*I
     """
     try: return x.asin()
@@ -162,4 +172,9 @@
     Return the arc tangent of x.
 
+    EXAMPLES:
+        sage: atan(1/2)
+        0.463647609001
+        sage: atan(1 + I)
+        1.01722196789785 + 0.402359478108525*I
     """
     try: return x.atan()
@@ -286,5 +301,5 @@
     EXAMPLES:
         sage: eta(1+I)
-        0.742048775837 + 0.19883137023*I
+        0.742048775836565 + 0.198831370229911*I
     """
     try: return x.eta()
@@ -330,9 +345,9 @@
     except AttributeError: return factor(charpoly(x, var))
 
-## def floor(x):
-##     try:
-##         return x.floor()
-##     except AttributeError:
-##         return sage.rings.all.floor(x)
+def floor(x):
+    try:
+        return x.floor()
+    except AttributeError:
+        return sage.rings.all.floor(x)
 
 def gen(x):
@@ -408,11 +423,11 @@
         sage: z = 1+2*I
         sage: imaginary(z)
-        2
+        2.00000000000000
         sage: imag(z)
-        2
+        2.00000000000000
     """
     return imag(x)
 
-def integral(x, *args, **kwds):
+def integral(x, var=None, algorithm='maxima'):
     """
     Return an indefinite integral of an object x.
@@ -426,18 +441,19 @@
         sage: integral(f)
         1/5*x^5 - 1/4*x^4 + 1/3*x^3 - 1/2*x^2 + x
-        sage: integral(sin(x),x)
-        -cos(x)
-        sage: integral(sin(x),y)
-        sin(x)*y
-        sage: integral(sin(x), x, 0, pi/2)
-        1
-        sage: sin(x).integral(x, 0,pi/2)
-        1        
-    """
-    if hasattr(x, 'integral'):
-        return x.integral(*args, **kwds)
+    """
+    if var is None:
+        try:
+            return x.integral()
+        except AttributeError:
+            pass
+    import sage.interfaces.all as I
+    if var is None:
+        var = 'x'
+    if algorithm == 'maxima':
+        return I.maxima(x).integrate(var)
+    elif algorithm == 'mathematica':
+        return I.mathematica(x).Integrate(var)
     else:
-        from sage.calculus.calculus import SR
-        return SR(x).integral(*args, **kwds)
+        raise ValueError, 'no algorithm %s'%algorithm
         
 def integral_closure(x):
@@ -588,4 +604,13 @@
     argument.}
 
+    EXAMPLES:
+        sage: log(10,2)
+        3.32192809489
+        sage: log(8,2)
+        3.0
+        sage: log(10)
+        2.30258509299
+        sage: log(2.718)
+        0.999896315728952
     """
     if b is None:
@@ -631,8 +656,4 @@
         sage: z = 1+2*I
         sage: norm(z)
-        5
-        sage: norm(CDF(z))
-        5.0
-        sage: norm(CC(z))
         5.00000000000000
     """
@@ -718,5 +739,5 @@
 
     We compute the rank of an elliptic curve:
-        sage: E = EllipticCurve([0,0,1,-1,0])
+        sage: E=EllipticCurve([0,0,1,-1,0])
         sage: rank(E)
         1
@@ -731,5 +752,5 @@
         sage: z = 1+2*I
         sage: real(z)
-        1
+        1.00000000000000
     """
     try: return x.real()
@@ -791,5 +812,5 @@
         print '<html><div class="math">%s</div></html>'%sage.misc.latex.latex(x)
         return sage.misc.latex.LatexExpr('') # so not visible output
-    raise AttributeError, "object %s does not support show."%(x, )
+    raise AttributeError, "object %s does not support show."%x
 
 def sqrt(x):
@@ -804,9 +825,5 @@
     """
     try: return x.sqrt()
-    except (AttributeError, ValueError):
-        try:
-            return RDF(x).sqrt()
-        except TypeError:
-            return CDF(x).sqrt()
+    except (AttributeError, ValueError): return CDF(x).sqrt()
 
 def isqrt(x):
@@ -862,19 +879,33 @@
 squarefree_part = square_free_part
     
-## def square_root(x):
-##     """
-##     Return a square root of x with the same parent as x, if possible,
-##     otherwise raise a ValueError.
-##     EXAMPLES:
-##         sage: square_root(9)
-##         3
-##         sage: square_root(100)
-##         10
-##     """
-##     try:
-##         return x.square_root()
-##     except AttributeError:
-##         raise NotImplementedError
+def square_root(x):
+    """
+    Return a square root of x with the same parent as x, if possible,
+    otherwise raise a ValueError.
+
+    EXAMPLES:
+        sage: square_root(9)
+        3
+        sage: square_root(100)
+        10
+    """
+    try:
+        return x.square_root()
+    except AttributeError:
+        raise NotImplementedError
     
+def tan(x):
+    """
+    Return the tangent of x.
+
+    EXAMPLES:
+        sage: tan(3.1415)
+        -0.0000926535900581913
+        sage: tan(3.1415/4)
+        0.999953674278156
+    """
+    try: return x.tan()
+    except AttributeError: return RDF(x).tan()
+
 def transpose(x):
     """
Index: sage/misc/hg.py
===================================================================
--- sage/misc/hg.py	(revision 4041)
+++ sage/misc/hg.py	(revision 3631)
@@ -35,5 +35,4 @@
 from   misc   import tmp_filename, branch_current_hg
 from   remote_file import get_remote_file
-from   sage.server.misc import print_open_msg
 
 def embedded():
@@ -155,6 +154,5 @@
             return out, err
 
-    def serve(self, port=8200, address='localhost',
-              open_viewer=True, options=''):
+    def serve(self, port=8200, open_viewer=False):
         """
         Start a web server for this repository.
@@ -166,19 +164,15 @@
         INPUT:
             port -- port that the server will listen on
-            address --  (default: 'localhost') address to listen on
-            open_viewer -- boolean (default: True); whether to pop up the web page
-            options -- a string passed directly to hg's serve command.
-        """
+            open_viewer -- boolean (default: False); whether to pop up the web page
+        """
+        print('Now serving repository on port %s'%port)
+        print("Point your web browser at http://localhost:%s"%port)
         if open_viewer:
-            cmd = 'sleep 1; %s http://%s:%s 1>&2 >/dev/null'%(browser(),
-                                                              address, port)
+            cmd = 'sleep 1; %s http://%s:%s 1>&2 >/dev/null'%(browser(), 'localhost', port)
             t = tmp_filename()
             open(t,'w').write(cmd)
             P = os.path.abspath(t)
             os.system('chmod +x %s; %s &'%(P, P))
-            
-        print_open_msg(address, port)
-        self('serve --address %s --port %s  %s'%(address, port, options))
-        print_open_msg(address, port)            
+        self('serve --port %s'%port)
 
     browse = serve
@@ -564,43 +558,4 @@
         self('%s --help | %s'%(cmd, pager()))
 
-    def outgoing(self, url=None, opts=''):
-        """
-        Use this to find changsets that are in your branch, but not in the
-        specified destination repository. If no destination is specified, the
-        official repository is used.
-
-        From the Mercurial documentation:
-            Show changesets not found in the specified destination repository or the
-            default push location. These are the changesets that would be pushed if
-            a push was requested.
-
-            See pull() for valid destination format details.
-
-        INPUT:
-            url:  default: self.url() -- the official repository
-                   * http://[user@]host[:port]/[path]
-                   * https://[user@]host[:port]/[path]
-                   * ssh://[user@]host[:port]/[path]
-                   * local directory (starting with a /)
-                   * name of a branch (for hg_sage); no /'s
-            options: (default: none)
-                 -M --no-merges     do not show merges
-                 -f --force         run even when remote repository is unrelated
-                 -p --patch         show patch
-                    --style         display using template map file
-                 -r --rev           a specific revision you would like to push
-                 -n --newest-first  show newest record first
-                    --template      display with template
-                 -e --ssh           specify ssh command to use
-                    --remotecmd     specify hg command to run on the remote side
-        """
-        if url is None:
-            url = self.__url
-
-        if not '/' in url:
-            url = '%s/devel/sage-%s'%(SAGE_ROOT, url)
-
-        self('outgoing %s %s | %s' % (opts, url, pager()))
-
     def pull(self, url=None, options='-u'):
         """
Index: sage/misc/misc.py
===================================================================
--- sage/misc/misc.py	(revision 4066)
+++ sage/misc/misc.py	(revision 3388)
@@ -21,5 +21,5 @@
                "assert_attribute", "LOGFILE"]
 
-import operator, os, sys, signal, time, weakref, random, resource
+import operator, os, sys, signal, time, weakref, random
 
 from banner import version, banner
@@ -113,7 +113,4 @@
     spent by subprocesses spawned by SAGE (e.g., Gap, Singular, etc.).
 
-    This is done via a call to resource.getrusage, so it avoids the
-    wraparound problems in time.clock() on Cygwin.
-
     INPUT:
         t -- (optional) float, time in CPU seconds
@@ -136,6 +133,5 @@
     except TypeError:
         t = 0.0
-    u,s = resource.getrusage(resource.RUSAGE_SELF)[:2] 
-    return u+s - t
+    return time.clock() - t
 
 def walltime(t=0):
@@ -227,4 +223,5 @@
         s = s + " (time = %s)"%cputime(t)
     print s
+    sys.stdout.flush()
     #open(LOGFILE,"a").write(s+"\n")
     return cputime()
Index: sage/misc/preparser.py
===================================================================
--- sage/misc/preparser.py	(revision 4061)
+++ sage/misc/preparser.py	(revision 3425)
@@ -8,6 +8,4 @@
                                      by digits of input (like mathematica).
     -- Joe Wetherell (2006-04-14): * added MAGMA-style constructor preparsing.
-    -- Bobby Moretti (2007-01-25): * added preliminary function assignment
-                                     notation
 
 EXAMPLES:
@@ -51,18 +49,4 @@
     SyntaxError: invalid syntax
 
-SYMBOLIC FUNCTIONAL NOTATION:
-    sage: a=10; f(theta, beta) = theta + beta; b = x^2 + theta
-    sage: f
-    (theta, beta) |--> theta + beta
-    sage: a
-    10
-    sage: b
-    x^2 + theta
-    sage: f(theta,theta)
-    2*theta
-    
-    sage: a = 5; f(x,y) = x*y*sqrt(a)
-    sage: f
-    (x, y) |--> sqrt(5)*x*y
     
 RAW LITERALS:
@@ -130,6 +114,6 @@
 #                  http://www.gnu.org/licenses/
 ###########################################################################
+
 import os
-import pdb
 
 def isalphadigit_(s):
@@ -140,18 +124,8 @@
 in_double_quote = False
 in_triple_quote = False
-
 def in_quote():
     return in_single_quote or in_double_quote or in_triple_quote
 
 def preparse(line, reset=True, do_time=False, ignore_prompts=False):
-
-    # find where the parens are for function assignment notation
-    oparen_index = -1 
-    cparen_index = -1
-
-    # for caclulus function notation:
-    paren_level = 0
-    first_eq_index = -1
-    
     global in_single_quote, in_double_quote, in_triple_quote
     line = line.rstrip()  # xreadlines leaves the '\n' at end of line
@@ -186,7 +160,4 @@
     in_number = False
     is_real = False
-
-    in_args = False
-
     if reset:
         in_single_quote = False
@@ -241,4 +212,5 @@
                 i += 1
                 continue
+
 
         # Decide if we should wrap a particular integer or real literal
@@ -269,10 +241,4 @@
                 continue
 
-        elif line[i] == ";" and not in_quote():
-            line = line[:i+1] + preparse(line[i+1:], reset, do_time, ignore_prompts)
-            i = len(line)
-            continue
-
-
         # Support for generator construction syntax:
         # "obj.<gen0,gen1,...,genN> = objConstructor(...)"
@@ -357,98 +323,4 @@
             continue
 
-        # Support for calculus-like function assignment, the line
-        # "f(x,y,z) = sin(x^3 - 4*y) + y^x"
-        # gets turnd into
-        # "f = SR(sin(x^3 - 4*y) + y^x).function(x,y,z)"
-        # AUTHORS:
-        #   - Bobby Moretti: initial version - 02/2007
-        #   - William Stein: make variables become defined if they aren't already defined.
-
-        elif (line[i] == "(") and not in_quote():
-            paren_level += 1
-            # we need to make sure that this is the first open paren we find
-            if oparen_index == -1:
-                oparen_index = i
-            i += 1
-            continue
-
-        elif (line[i] == ")") and not in_quote():
-            cparen_index = i
-            paren_level -= 1
-            i += 1
-            continue
-
-        elif (line[i] == "=") and paren_level == 0 and not in_quote():
-            if first_eq_index == -1:
-                first_eq_index = i
-            eq = i
-
-            if cparen_index == -1:
-                i += 1
-                continue
- 
-            # make sure the '=' sign is on its own, reprsenting assignment
-            eq_chars = ["=", "!", ">", "<", "+", "-", "*", "/", "^"]
-            if line[eq-1] in eq_chars or line[eq+1] in eq_chars:
-                i += 1
-                continue
-
-            line_before = line[:oparen_index].strip()
-            if line_before == "" or not line_before.isalnum():
-                i += 1
-                continue
-
-            if eq != first_eq_index:
-                i += 1
-                continue
-
-            vars_end = cparen_index
-            vars_begin = oparen_index+1
-
-            # figure out where the line ends
-            line_after = line[vars_end+1:]
-            try:
-                a = line.index("#")
-            except ValueError:
-                a = len(line)
-
-            try:
-                b = line.index(";")
-            except ValueError:
-                b = len(line)
-
-            a =  min(a,b)
-           
-            vars = line[vars_begin:vars_end].split(",")
-            vars = [v.strip() for v in vars]
-            b = []
-
-            
-            # construct the parsed line
-            k = line[:vars_begin-1].rfind(';')
-            if k == -1:
-                k = len(line) - len(line.lstrip())
-            b.append(line[:k])
-            b.append('_=var("%s");'%(','.join(vars)))
-            b.append(line[k:vars_begin-1])
-            b.append('=')
-            b.append('symbolic_expression(')
-            b.append(line[eq+1:a].strip())
-            b.append(').function(')
-            b.append(','.join(vars))
-            b.append(')')
-            b.append(line[a:])
-
-            line =  ''.join(b)
-            
-            # i should get set to the position of the first paren after the new
-            # assignment operator
-            n = len(line_before)
-            i = line.find('=', n) + 2
-
-            continue
-        #    
-        ####### END CALCULUS ########
-
         # exponents can be either ^ or **
         elif line[i] == "^" and not in_quote():
Index: age/misc/reset.pyx
===================================================================
--- sage/misc/reset.pyx	(revision 4022)
+++ 	(revision )
@@ -1,102 +1,0 @@
-import sys
-
-def reset(vars=None):
-    """
-    Delete all user defined variables, reset all globals variables
-    back to their default state, and reset all interfaces to other
-    computer algebra systems.
-
-    If vars is specified, just restore the value of vars and leave
-    all other variables alone (i.e., call restore).
-
-    INPUT:
-        vars -- (default: None), a list, or space or comma separated
-        string.
-    """
-    if not vars is None:
-        restore(vars)
-        return
-    G = globals()  # this is the reason the code must be in SageX.
-    T = type(sys)
-    for k in G.keys():
-        if k[0] != '_' and type(k) != T:
-            try:
-                del G[k]
-            except KeyError:
-                pass
-    restore()
-    reset_interfaces()
-
-
-def restore(vars=None):
-    """
-    Restore predefined global variables to their default values.
-
-    INPUT:
-       vars -- string or list (default: None) if not None, restores
-               just the given variables to the default value.
-
-    EXAMPLES:
-        sage: x = 10; y = 15/3; QQ='red'
-        sage: QQ
-        'red'
-        sage: restore('QQ')
-        sage: QQ
-        Rational Field
-        sage: x
-        10
-        sage: restore('x  y')
-        sage: x
-        x
-        sage: y
-        y
-        sage: x = 10; y = 15/3; QQ='red'
-        sage: ww = 15
-        sage: restore()
-        sage: x,y,QQ,ww
-        (x, y, Rational Field, 15)
-        sage: restore('ww')
-        sage: ww
-        Traceback (most recent call last):
-        ...
-        NameError: name 'ww' is not defined
-    """
-    G = globals()  # this is the reason the code must be in SageX.
-    import sage.all
-    D = sage.all.__dict__
-    if vars is None:
-        for k, v in D.iteritems():
-            G[k] = v
-    else:
-        if isinstance(vars, str):
-            if ',' in vars:
-                vars = vars.split(',')
-            else:
-                vars = vars.split()
-        for k in vars:
-            if D.has_key(k):
-                G[k] = D[k]
-            else:
-                try:
-                    del G[k]      # the default value was "unset"
-                except KeyError:
-                    pass
-
-
-def reset_interfaces():
-    from sage.interfaces.quit import expect_quitall
-    expect_quitall()
-    
-##     import sys
-##     M = sys.modules
-##     for k in M.keys():
-##         if 'sage.interfaces' in k:
-##             if not M[k] is None:
-##                 reload(M[k])
-
-##     import sage.interfaces.all
-##     G = globals()
-##     for k, v in sage.interfaces.all.__dict__.iteritems():
-##         G[k] = v
-
-
Index: sage/misc/search.pyx
===================================================================
--- sage/misc/search.pyx	(revision 3908)
+++ sage/misc/search.pyx	(revision 1319)
@@ -30,6 +30,5 @@
     Return (True,i) where i is such that v[i] == x if there is such an i,
     or (False,j) otherwise, where j is the position that a should be inserted
-    so that v remains sorted.
-    
+    so that v remains sorted. 
     INPUT:
         v -- a list, which is assumed sorted
Index: sage/modular/cusps.py
===================================================================
--- sage/modular/cusps.py	(revision 4061)
+++ sage/modular/cusps.py	(revision 3311)
@@ -102,6 +102,5 @@
             Traceback (most recent call last):
             ...
-            TypeError: Unable to coerce I (<class 'sage.functions.constants.I_class'>) to Rational
-            
+            TypeError: Unable to coerce 1.00000000000000*I (<type 'sage.rings.complex_number.ComplexNumber'>) to Rational
         """
         return Cusp(x, parent=self)
@@ -169,6 +168,6 @@
             Traceback (most recent call last):
             ...
-            TypeError: unable to convert I to a rational
-
+            TypeError: Unable to coerce 1.00000000000000*I (<type 'sage.rings.complex_number.ComplexNumber'>) to Rational
+            
             sage: a = Cusp(2,3)
             sage: loads(a.dumps()) == a
Index: sage/modular/dirichlet.py
===================================================================
--- sage/modular/dirichlet.py	(revision 4003)
+++ sage/modular/dirichlet.py	(revision 3570)
@@ -672,5 +672,5 @@
             sage: abs(e.gauss_sum_numerical())
             1.73205080756888
-            sage: sqrt(3.0)
+            sage: sqrt(3)
             1.73205080756888
             sage: e.gauss_sum_numerical(a=2)
@@ -684,5 +684,5 @@
             sage: abs(e.gauss_sum_numerical())
             3.60555127546399
-            sage: sqrt(13.0)
+            sage: sqrt(13)
             3.60555127546399
         """
Index: sage/modular/modform/all.py
===================================================================
--- sage/modular/modform/all.py	(revision 3884)
+++ sage/modular/modform/all.py	(revision 3388)
@@ -14,4 +14,5 @@
 
 from hecke_operator_on_qexp import (hecke_operator_on_qexp,
-                                    hecke_operator_on_basis)                                    
+                                    hecke_operator_on_basis)
+
 from numerical import NumericalEigenforms as numerical_eigenforms
Index: sage/modular/modform/element.py
===================================================================
--- sage/modular/modform/element.py	(revision 4059)
+++ sage/modular/modform/element.py	(revision 3616)
@@ -103,6 +103,6 @@
         return chi
     
-    def __nonzero__(self):
-        return not self.element().is_zero()
+    def is_zero(self):
+        return self.element().is_zero()
     
     def level(self):
Index: sage/modular/modform/numerical.py
===================================================================
--- sage/modular/modform/numerical.py	(revision 3982)
+++ sage/modular/modform/numerical.py	(revision 3621)
@@ -247,5 +247,4 @@
             [28.0, 28.0, -7.92820323028, 5.92820323028]
             sage: m = n.modular_symbols()
-            sage: x = polygen(QQ, 'x')
             sage: m.T(2).charpoly(x).factor()
             (x - 9)^2 * (x^2 - 2*x - 2)
Index: sage/modular/modsym/boundary.py
===================================================================
--- sage/modular/modsym/boundary.py	(revision 3907)
+++ sage/modular/modsym/boundary.py	(revision 3520)
@@ -67,9 +67,5 @@
         """
         self.__x = x
-        self.__vec = parent.free_module()(x)
-        hecke.HeckeModuleElement.__init__(self, parent, self.__vec)
-
-    def coordinate_vector(self):
-        return self.__vec
+        hecke.HeckeModuleElement.__init__(self, parent, parent.free_module()(x))
 
     def _repr_(self):
Index: sage/modular/modsym/space.py
===================================================================
--- sage/modular/modsym/space.py	(revision 4013)
+++ sage/modular/modsym/space.py	(revision 3569)
@@ -522,5 +522,4 @@
 
         An example that (somewhat spuriously) is over a number field:
-            sage: x = polygen(QQ)
             sage: k = NumberField(x^2+1, 'a')
             sage: M = ModularSymbols(11, base_ring=k, sign=1).cuspidal_submodule()
@@ -1594,5 +1593,4 @@
         self.__domain = modsym.ambient_module()
         self.__A = A
-        A.set_immutable()
 
     def modular_symbols_space(self):
Index: sage/modules/free_module_element.pyx
===================================================================
--- sage/modules/free_module_element.pyx	(revision 3887)
+++ sage/modules/free_module_element.pyx	(revision 3544)
@@ -543,5 +543,5 @@
         l = self.list()
         if len(r) != len(l):
-            raise ArithmeticError, "degrees (%s and %s) must be the same"%(len(l),len(r))
+            raise ArithmeticError, "degrees must be the same"%(len(l),len(r))
         zero = self.parent().base_ring()(0)
         return sum(eval('[l[i]*r[i] for i in xrange(len(l))]', {'l':l,'r':r}), zero)
Index: sage/modules/real_double_vector.pyx
===================================================================
--- sage/modules/real_double_vector.pyx	(revision 4021)
+++ sage/modules/real_double_vector.pyx	(revision 3616)
@@ -333,36 +333,4 @@
         memcpy(self.v.data,p,self.v.size*sizeof(double))
 
-    #############################
-    # statistics
-    #############################
-    def mean(self):
-        return gsl_stats_mean(self.v.data, self.v.stride, self.v.size)
-
-    def variance(self):
-        return gsl_stats_variance(self.v.data, self.v.stride, self.v.size)
-
-    #def covariance(self):
-    #    return gsl_stats_covariance(self.v.data, self.v.stride, self.v.size)
-
-    def standard_deviation(self):
-        """
-        EXAMPLES:
-        sage: v = vector(RDF, 5, [1,2,3,4,5])
-        sage: v.standard_deviation()
-        1.5811388300841898
-        """
-        return gsl_stats_sd(self.v.data, self.v.stride, self.v.size)
-
-    def stats_skew(self):
-        return gsl_stats_skew(self.v.data, self.v.stride, self.v.size)
-
-    def stats_kurtosis(self):
-        return gsl_stats_kurtosis(self.v.data, self.v.stride, self.v.size)
-    
-    def stats_lag1_autocorrelation(self):
-        return gsl_stats_lag1_autocorrelation(self.v.data, self.v.stride, self.v.size)
-    
-    
-    
 def unpickle_v0(parent, entries, degree):
     # If you think you want to change this function, don't.
Index: sage/monoids/free_monoid.py
===================================================================
--- sage/monoids/free_monoid.py	(revision 4007)
+++ sage/monoids/free_monoid.py	(revision 1840)
@@ -154,8 +154,6 @@
         """
         ## There should really some careful type checking here...
-        if isinstance(x, FreeMonoidElement) and x.parent() is self:
-                return x
         if isinstance(x, FreeMonoidElement) and x.parent() == self:
-            return FreeMonoidElement(self,x._element_list,check)
+            return x
         elif isinstance(x, (int, long, Integer)) and x == 1:
             return FreeMonoidElement(self, x, check) 
Index: sage/monoids/free_monoid_element.py
===================================================================
--- sage/monoids/free_monoid_element.py	(revision 4007)
+++ sage/monoids/free_monoid_element.py	(revision 1859)
@@ -67,21 +67,21 @@
             raise TypeError, "Argument x (= %s) is of the wrong type."%x
 
-##     def __cmp__(left, right):
-##         """
-##         Compare two free monoid elements with the same parents.
-
-##         The ordering is the one on the underlying sorted list of
-##         (monomial,coefficients) pairs.
-
-##         EXAMPLES:
-##             sage: R.<x,y> = FreeMonoid(2)
-##             sage: x < y
-##             True
-##             sage: x * y < y * x
-##             True
-##             sage: x * y * x^2 < x * y * x^3
-##             True        
-##         """
-##         return cmp(left._element_list, right._element_list)
+    def __cmp__(left, right):
+        """
+        Compare two free monoid elements with the same parents.
+
+        The ordering is the one on the underlying sorted list of
+        (monomial,coefficients) pairs.
+
+        EXAMPLES:
+            sage: R.<x,y> = FreeMonoid(2)
+            sage: x < y
+            True
+            sage: x * y < y * x
+            True
+            sage: x * y * x^2 < x * y * x^3
+            True        
+        """
+        return cmp(left._element_list, right._element_list)
                                         
     def _repr_(self):
@@ -254,3 +254,4 @@
                     return 1
         return 0 # x = self and y are equal
-
+    
+
Index: sage/plot/plot.py
===================================================================
--- sage/plot/plot.py	(revision 4064)
+++ sage/plot/plot.py	(revision 3584)
@@ -81,8 +81,7 @@
 see the first few zeros:
 
-    sage: i = CDF.0      # define i this way for maximum speed.
-    sage: p1 = plot(lambda t: arg(zeta(0.5+t*i)), 1,27,rgbcolor=(0.8,0,0))
-    sage: p2 = plot(lambda t: abs(zeta(0.5+t*i)), 1,27,rgbcolor=hue(0.7))
-    sage: p1 + p2
+    sage: p1 = plot(lambda t: arg(zeta(0.5+t*I)), 1,27,rgbcolor=(0.8,0,0))
+    sage: p2 = plot(lambda t: abs(zeta(0.5+t*I)), 1,27,rgbcolor=hue(0.7))
+    sage: p1+p2
     Graphics object consisting of 2 graphics primitives
     sage: (p1+p2).save()
@@ -96,11 +95,4 @@
     ...
     sage: g.save(dpi=200, axes=False)
-
-Another graph:
-    sage: P = plot(lambda x: sin(x)/x, -4,4, rgbcolor=(0,0,1)) + \
-    ...    plot(lambda x: x*cos(x), -4,4, rgbcolor=(1,0,0)) + \
-    ...    plot(lambda x: tan(x),-4,4,rgbcolor=(0,1,0))
-    ...
-    sage: P.save('sage.png', ymin=-pi,ymax=pi)
     
 AUTHORS:
@@ -127,6 +119,4 @@
 #                  http://www.gnu.org/licenses/
 #*****************************************************************************
-
-import pdb
 
 from sage.structure.sage_object import SageObject
@@ -471,6 +461,8 @@
   
         EXAMPLES:
-            sage: g1 = plot(abs(sqrt(x^3  - 1)), 1, 5)
-            sage: g2 = plot(-abs(sqrt(x^3  - 1)), 1, 5)
+            sage: h1 = lambda x : abs(sqrt(x^3  - 1))
+            sage: h2 = lambda x : -abs(sqrt(x^3  - 1))
+            sage: g1 = plot(h1, 1, 5)
+            sage: g2 = plot(h2, 1, 5)
             sage: h = g1 + g2
             sage: h.save()
@@ -1738,23 +1730,5 @@
     and plots contour lines of the function over the specified 
     xrange and yrange as demonstrated below.
-
-      contour_plot(f, (xmin, xmax), (ymin, ymax), ...)
-
-    INPUT:
-        f -- a function of two variables
-        (xmin, xmax) -- 2-tuple, the range of x values
-        (ymin, ymax) -- 2-tuple, the range of y values
-    The following inputs must all be passed in as named parameters:
-        plot_points  -- integer (default: 25); number of points to plot
-                        in each direction of the grid
-        fill         -- bool (default: True), whether to color in the area
-                        between contour lines
-        cmap         -- string (default: 'gray'), the color map to use:
-                        autumn, bone, cool, copper, gray, hot, hsv,
-                        jet, pink, prism, spring, summer, winter
-        contours     -- integer (default: None), the number of contour
-                        lines to draw.  If None, determined automatically,
-                        and usually about 5.
-        
+    contour_plot(f, (xmin, xmax), (ymin, ymax))
 
     EXAMPLES:
@@ -1895,5 +1869,6 @@
     A red, blue, and green "cool cat":
 
-        sage: G = plot(-cos(x), -2, 2, thickness=5, rgbcolor=(0.5,1,0.5))
+        sage: ncos = lambda x: -cos(x)
+        sage: G = plot(ncos, -2, 2, thickness=5, rgbcolor=(0.5,1,0.5))
         sage: P = polygon([[1,2], [5,6], [5,0]], rgbcolor=(1,0,0))
         sage: Q = polygon([(-x,y) for x,y in P[0]], rgbcolor=(0,0,1))
@@ -2251,5 +2226,5 @@
     We can change the line style to one of '--' (dashed), '-.' (dash dot),
     '-' (solid), 'steps', ':' (dotted):
-        sage: g = plot(sin(x), 0, 10, linestyle='-.')
+        sage: g = plot(sin,0,10, linestyle='-.')
         sage: g.save('sage.png')
     """
@@ -2257,7 +2232,6 @@
         o = self.options
         o['plot_points'] = 200
-        o['plot_division'] = 1000 
-        o['max_bend'] = 0.1       
-        o['rgbcolor'] = (0,0,1)   
+        o['plot_division'] = 1000 # is this a good value?
+        o['max_bend'] = 0.1       # is this good as well?
 
     def _repr_(self):
@@ -2265,5 +2239,6 @@
 
     def __call__(self, funcs, xmin=None, xmax=None, parametric=False,
-                 polar=False, label='', show=None, **kwds):
+                 polar=False, label='',
+                 show=None, **kwds):
         if show is None:
             show = SHOW_DEFAULT
@@ -2282,4 +2257,5 @@
         except AttributeError:
             pass
+        
         if xmin is None:
             xmin = -1
@@ -2312,5 +2288,4 @@
         data = []
         dd = delta
-        exceptions = 0; msg=''
         for i in xrange(plot_points + 1):
             x = xmin + i*delta
@@ -2321,16 +2296,10 @@
             else:
                 x = xmax  # guarantee that we get the last point.
-                
             try:
                 y = f(x)
                 data.append((x, float(y)))
-            except (ZeroDivisionError, TypeError, ValueError), msg:
-                sage.misc.misc.verbose("%s\nUnable to compute f(%s)"%(msg, x),1)
-                exceptions += 1
+            except (TypeError, ValueError), msg:
+                #raise ValueError, "%s\nUnable to compute f(%s)"%(msg, x)
                 pass
-
-        if (len(data) == 0 and exceptions > 0) or exceptions > 10:
-            print "WARNING: When plotting, failed to evaluate function at %s points."%exceptions
-            print "Last error message: '%s'"%msg
         # adaptive refinement
         i, j = 0, 0
@@ -2434,5 +2403,7 @@
 
     EXAMPLE:
-        sage: G = parametric_plot( (sin(t), sin(2*t)), 0, 2*pi, rgbcolor=hue(0.6) )
+        sage: f = lambda t: sin(t)
+        sage: g = lambda t: sin(2*t)
+        sage: G = parametric_plot((f,g),0,2*pi,rgbcolor=hue(0.6))
         sage: G.save()
     """
@@ -2779,7 +2750,7 @@
     Make some plots of $\sin$ functions:
     
-        sage: f(x) = sin(x)
-        sage: g(x) = sin(2*x)
-        sage: h(x) = sin(4*x)
+        sage: f = lambda x: sin(x)
+        sage: g = lambda x: sin(2*x)
+        sage: h = lambda x: sin(4*x)
         sage: p1 = plot(f,-2*pi,2*pi,rgbcolor=hue(0.5))
         sage: p2 = plot(g,-2*pi,2*pi,rgbcolor=hue(0.9))
@@ -2820,8 +2791,8 @@
     """ # TODO: figure out WTF
     from sage.rings.integer import Integer
-    from math import floor
-    rr = Integer(int(floor(r*255))).str(base=16)
-    gg = Integer(int(floor(g*255))).str(base=16)
-    bb = Integer(int(floor(b*255))).str(base=16)
+    from sage.rings.arith import floor
+    rr = Integer(floor(r*255)).str(base=16)
+    gg = Integer(floor(g*255)).str(base=16)
+    bb = Integer(floor(b*255)).str(base=16)
     rr = '0'*(2-len(rr)) + rr
     gg = '0'*(2-len(gg)) + gg
@@ -2844,5 +2815,5 @@
         ['#ff0000', '#ffda00', '#48ff00', '#00ff91', '#0091ff', '#4800ff', '#ff00da']
     """
-    from math import floor
+    from sage.rings.arith import floor
     R = []
     for i in range(n):
Index: sage/probability/random_variable.py
===================================================================
--- sage/probability/random_variable.py	(revision 4022)
+++ sage/probability/random_variable.py	(revision 2617)
@@ -2,8 +2,7 @@
 Random variables and probability spaces
 
-This introduces a class of random variables, with the focus on
-discrete random variables (i.e. on a discrete probability space).
-This avoids the problem of defining a measure space and measurable
-functions.
+This introduces a class of random variables, with the focus on discrete random 
+variables (i.e. on a discrete probability space).  This avoids the problem of 
+defining a measure space and measurable functions.
 """
 
Index: sage/quadratic_forms/binary_qf.py
===================================================================
--- sage/quadratic_forms/binary_qf.py	(revision 4063)
+++ sage/quadratic_forms/binary_qf.py	(revision 1894)
@@ -268,5 +268,5 @@
 
     ## Find the range of allowed b's
-    bmax = (-D / ZZ(3)).sqrt_approx().ceil()
+    bmax = (-D / ZZ(3)).sqrt().ceil()
     b_range = range(-bmax, bmax+1)
     
Index: sage/rings/arith.py
===================================================================
--- sage/rings/arith.py	(revision 4065)
+++ sage/rings/arith.py	(revision 3595)
@@ -62,5 +62,5 @@
 
     This example involves a complex number.
-        sage: z = (1/2)*(1 + RDF(sqrt(3)) *CC.0); z
+        sage: z = (1/2)*(1 + sqrt(3) *CC.0); z
         0.500000000000000 + 0.866025403784439*I
         sage: p = algdep(z, 6); p
@@ -1224,5 +1224,5 @@
         1/8
     """
-    if bool(a == one):
+    if a == one:
         return a
     if m < 0:
@@ -1483,5 +1483,5 @@
 # primes at most a given limit.
 
-def factor(n, proof=True, int_=False, algorithm='pari', verbose=0, **kwds):
+def factor(n, proof=True, int_=False, algorithm='pari', verbose=0):
     """
     Returns the factorization of the integer n as a sorted list of
@@ -1536,5 +1536,5 @@
     if not isinstance(n, (int,long, integer.Integer)):
         try:
-            return n.factor(**kwds)
+            return n.factor()
         except AttributeError:
             raise TypeError, "unable to factor n"
@@ -1874,8 +1874,9 @@
         -1
 
-    IMPLEMENTATION: Using GMP.
+    IMPLEMENTATION: Using Pari.
     """
     x = integer_ring.ZZ(x)
-    return integer_ring.ZZ(x.kronecker(y))
+    y = integer_ring.ZZ(y)    
+    return integer_ring.ZZ(pari(x).kronecker(y).python())
 
 def kronecker(x,y):
@@ -2260,5 +2261,5 @@
         [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1]
         sage: continued_fraction_list(sqrt(4/19))
-        [0, 2, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1, 18]
+        [0, 2, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1, 15, 2]
         sage: continued_fraction_list(RR(pi), partial_convergents=True)
         ([3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3],
@@ -2284,21 +2285,6 @@
         [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1, 14, 1, 1, 16, 1, 1, 18, 1, 1, 20, 1, 1, 22, 1, 1, 24, 1, 1, 26, 1, 1, 28, 1, 1, 30, 1, 1, 32, 1, 1, 34, 1, 1, 36, 1, 1, 38, 1, 1]
     """
-    import sage.calculus.calculus
-    import sage.functions.constants
-    # if x is a SymbolicExpression, try coercing it to a real number
     if not bits is None:
-        try:
-            x = sage.rings.real_mpfr.RealField(bits)(x)
-        except  TypeError:
-            raise TypeError, "can only find the continued fraction of a number"
-    elif isinstance(x, float):
-        from real_double import RDF
-        x = RDF(x)
-    elif isinstance(x, (sage.calculus.calculus.SymbolicExpression,
-                        sage.functions.constants.Constant)):
-        try:
-            x = sage.rings.real_mpfr.RealField(53)(x)
-        except TypeError:
-            raise TypeError, "can only find the continued fraction of a number"
+        x = sage.rings.real_mpfr.RealField(bits)(x)
     elif not partial_convergents and \
            isinstance(x, (integer.Integer, sage.rings.rational.Rational,
@@ -2630,9 +2616,7 @@
         0.652965496420167 + 0.343065839816545*I
         sage: falling_factorial(1+I, 4)
-        (I - 2)*(I - 1)*I*(I + 1)
-        sage: expand(falling_factorial(1+I, 4))
-        4*I + 2
+        2.00000000000000 + 4.00000000000000*I
         sage: falling_factorial(I, 4)
-        (I - 3)*(I - 2)*(I - 1)*I
+        -10.0000000000000
 
         sage: M = MatrixSpace(ZZ, 4, 4)
@@ -2693,12 +2677,10 @@
         0.266816390637832 + 0.122783354006372*I
     
-        sage: a = rising_factorial(I, 4); a
-        I*(I + 1)*(I + 2)*(I + 3)
-        sage: expand(a)
-        -10
+        sage: rising_factorial(I, 4)
+        -10.0000000000000
     
     See falling_factorial(I, 4).
     
-        sage: x = polygen(ZZ)
+        sage: R = ZZ['x']
         sage: rising_factorial(x, 4)
         x^4 + 6*x^3 + 11*x^2 + 6*x 
@@ -2715,11 +2697,7 @@
 
 
-def integer_ceil(x):
+def ceil(x):
     """
     Return the ceiling of x.
-
-    EXAMPLES:
-        sage: integer_ceil(5.4)
-        6
     """
     try: 
@@ -2730,7 +2708,9 @@
         except TypeError:
             pass
-    raise NotImplementedError, "computation of floor of %s not implemented"%repr(x)
-
-def integer_floor(x):
+    raise NotImplementedError, "computation of floor of %s not implemented"%x
+
+ceiling = ceil
+
+def floor(x):
     r"""
     Return the largest integer $\leq x$.
@@ -2743,11 +2723,11 @@
 
     EXAMPLES:
-        sage: integer_floor(5.4)
+        sage: floor(5.4)
         5
-        sage: integer_floor(float(5.4))
+        sage: floor(float(5.4))
         5
-        sage: integer_floor(-5/2)
+        sage: floor(-5/2)
         -3
-        sage: integer_floor(RDF(-5/2))
+        sage: floor(RDF(-5/2))
         -3
     """
Index: sage/rings/complex_double.pyx
===================================================================
--- sage/rings/complex_double.pyx	(revision 4060)
+++ sage/rings/complex_double.pyx	(revision 3370)
@@ -82,8 +82,4 @@
 CC = complex_field.ComplexField()
 
-import real_mpfr
-RR = real_mpfr.RealField()
-
-from real_double import RealDoubleElement
 
 # PREC is the precision (in decimal digits) that all PARI computations with doubles
@@ -99,9 +95,4 @@
 from random import random
 
-from sage.structure.parent_gens import ParentWithGens
-
-def is_ComplexDoubleField(x):
-    return bool(PY_TYPE_CHECK(x, ComplexDoubleField_class))
-
 cdef class ComplexDoubleField_class(sage.rings.ring.Field):
     """
@@ -110,7 +101,4 @@
     ALGORITHM: Arithmetic is done using GSL (the GNU Scientific Library).
     """
-    def __init__(self):
-        ParentWithGens.__init__(self, self, ('x',), normalize=False)
-
     def is_exact(self):
         return False
@@ -236,6 +224,4 @@
                 else:
                     return t
-            elif hasattr(x, '_complex_double_'):
-                return x._complex_double_(self)
             else:
                 return ComplexDoubleElement(x, 0)
@@ -261,12 +247,26 @@
             3.4
 
-        Thus the sum of a CDF and a symbolic object is symbolic:
+        Symbolic constants canonically coerce into the complex double field,
+        but CDF does not canonically coerce to symbolic constants:
+            sage: CDF._coerce_(pi)
+            3.14159265359
+            sage: R = parent(pi)
+            sage: R(CDF.0)
+            1.0*I
+            sage: R._coerce_(CDF.0)
+            Traceback (most recent call last):
+            ...
+            TypeError: no canonical coercion of element into self.
+
+        Thus the sum of a CDF and a symbolic constant is in CDF:
             sage: a = pi + CDF.0; a
-            1.00000000000000*I + pi
+            3.14159265359 + 1.0*I
             sage: parent(a)
-            Symbolic Ring
-        """
+            Complex Double Field        
+        """
+        import sage.functions.constants
         return self._coerce_try(x, [self.real_double_field(),
-                                    CC, RR])
+                                    sage.functions.constants.ConstantRing,
+                                    CC])
 
 
@@ -656,11 +656,11 @@
             0.0
             sage: CDF(0,1).arg()
-            1.57079632679
+            1.5707963267948966
             sage: CDF(0,-1).arg()
-            -1.57079632679
+            -1.5707963267948966
             sage: CDF(-1,0).arg()
-            3.14159265359
-        """
-        return RealDoubleElement(gsl_complex_arg(self._complex))
+            3.1415926535897931        
+        """
+        return gsl_complex_arg(self._complex)
 
     def __abs__(self):
@@ -670,5 +670,5 @@
         EXAMPLES:
             sage: abs(CDF(1,2))
-            2.2360679775
+            2.2360679774997898
             sage: abs(CDF(1,0))
             1.0
@@ -676,5 +676,5 @@
             3.6055512754639891        
         """
-        return RealDoubleElement(gsl_complex_abs(self._complex))
+        return gsl_complex_abs(self._complex)
 
     def abs(self):
@@ -686,5 +686,5 @@
             3.6055512754639891        
         """
-        return RealDoubleElement(gsl_complex_abs(self._complex))
+        return gsl_complex_abs(self._complex)
     
     def abs2(self):
@@ -697,5 +697,5 @@
             13.0        
         """
-        return RealDoubleElement(gsl_complex_abs2(self._complex))
+        return gsl_complex_abs2(self._complex)
 
     def norm(self):
@@ -708,5 +708,5 @@
             13.0        
         """
-        return RealDoubleElement(gsl_complex_abs2(self._complex))
+        return gsl_complex_abs2(self._complex)
 
     def logabs(self):
@@ -720,14 +720,19 @@
 
         EXAMPLES:
+        We try it out. 
             sage: CDF(1.1,0.1).logabs()
-            0.0994254293726
+            0.099425429372582669
             sage: log(abs(CDF(1.1,0.1)))
             0.0994254293726
 
+        Which is better?  
             sage: log(abs(ComplexField(200)(1.1,0.1)))
             0.099425429372582675602989386713555936556752871164033127857198
-        """
-        return RealDoubleElement(gsl_complex_logabs(self._complex))
-
+
+        Indeed, the logabs, wins.            
+        """
+        return gsl_complex_logabs(self._complex)
+
+    # TODO: real and imag should be elements of RealDoubleField, when that exists. 
     def real(self):
         """
@@ -739,5 +744,5 @@
             3.0
         """
-        return RealDoubleElement(self._complex.dat[0])
+        return self._complex.dat[0]
 
     def imag(self):
@@ -750,5 +755,5 @@
             -2.0
         """
-        return RealDoubleElement(self._complex.dat[1])
+        return self._complex.dat[1]
 
     def parent(self):
@@ -844,11 +849,5 @@
             0.5 + 0.866025403784*I
             sage: a^3                  # slightly random-ish arch dependent output
-            -1.0 + 1.22460635382e-16*I
-
-        We raise to symbolic powers:
-            sage: CDF(1.2)^x
-            1.20000000000000^x
-            sage: CDF(1.2)^(x^n + n^x)
-            1.20000000000000^(x^n + n^x)
+            -1.0 + 1.22460635382e-16*I   
         """
         try:
@@ -859,12 +858,5 @@
         except TypeError:
             # a is not a complex number
-            try:
-                return z._pow_(CDF(a))
-            except TypeError:
-                try:
-                    return a.parent()(z)**a
-                except AttributeError:
-                    raise TypeError
-                
+            return z._pow_(CDF(a))
 
     def exp(self):
@@ -1259,5 +1251,5 @@
             sage: z = CDF(1,1); z.eta()
             0.742048775837 + 0.19883137023*I
-            sage: i = CDF(0,1); pi = CDF(pi)
+            sage: i = CDF(0,1)
             sage: exp(pi * i * z / 12) * prod([1-exp(2*pi*i*n*z) for n in range(1,10)])
             0.742048775837 + 0.19883137023*I
@@ -1267,5 +1259,4 @@
             sage: z.eta(omit_frac=True)
             0.998129069926
-            sage: pi = CDF(pi)
             sage: prod([1-exp(2*pi*i*n*z) for n in range(1,10)])      # slightly random-ish arch dependent output
             0.998129069926 + 4.5908467128e-19*I  
@@ -1349,7 +1340,6 @@
         
         EXAMPLES:
-            sage: i = CDF(I)
-            sage: (1+i).agm(2-i)
-            1.62780548487 + 0.136827548397*I
+            sage: (1+I).agm(2-I)
+            1.62780548487271 + 0.136827548397369*I
         """
         cdef pari_sp sp
@@ -1439,5 +1429,5 @@
         
         EXAMPLE:
-            sage: z = (1/2)*(1 + RDF(sqrt(3)) *CDF.0); z
+            sage: z = (1/2)*(1 + sqrt(3) *CDF.0); z
             0.5 + 0.866025403784*I
             sage: p = z.algdep(5); p
Index: sage/rings/complex_field.py
===================================================================
--- sage/rings/complex_field.py	(revision 4057)
+++ sage/rings/complex_field.py	(revision 3290)
@@ -30,5 +30,5 @@
 
 cache = {}
-def ComplexField(prec=53, names=None):
+def ComplexField(prec=53):
     """
     Return the complex field with real and imaginary parts having prec
@@ -42,7 +42,4 @@
         sage: ComplexField(100).base_ring()
         Real Field with 100 bits of precision
-        sage: i = ComplexField(200).gen()
-        sage: i^2
-        -1.0000000000000000000000000000000000000000000000000000000000
     """
     global cache
@@ -102,7 +99,4 @@
         sage: loads(CC.dumps()) == CC
         True
-        sage: k = ComplexField(100)
-        sage: loads(dumps(k)) == k
-        True
 
     This illustrates basic properties of a complex field.
@@ -127,7 +121,4 @@
         self._prec = int(prec)
         ParentWithGens.__init__(self, self._real_field(), ('I',), False)
-
-    def __reduce__(self):
-        return ComplexField, (self._prec, )
 
     def is_exact(self):
Index: sage/rings/complex_number.pyx
===================================================================
--- sage/rings/complex_number.pyx	(revision 4059)
+++ sage/rings/complex_number.pyx	(revision 3484)
@@ -38,5 +38,5 @@
 
 def is_ComplexNumber(x):
-    return bool(isinstance(x, ComplexNumber))
+    return isinstance(x, ComplexNumber)
 
 cdef class ComplexNumber(sage.structure.element.FieldElement):
@@ -45,5 +45,6 @@
 
     EXAMPLES:
-        sage: I = CC.0
+        sage: C = ComplexField()
+        sage: I = C.0
         sage: b = 1.5 + 2.5*I
         sage: loads(b.dumps()) == b
@@ -116,9 +117,9 @@
 
         EXAMPLES:
-            sage: a = CC(1 + I)
+            sage: a = 1+I
             sage: loads(dumps(a)) == a
             True
         """
-        # TODO: This is potentially slow -- make a 1 version that
+        # TODO: This is potentially very slow -- make a 1 version that
         # is native and much faster -- doesn't use .real()/.imag()
         return (make_ComplexNumber0, (self._parent, self._multiplicative_order, self.real(), self.imag()))
@@ -260,5 +261,5 @@
         """
         EXAMPLES:
-            sage: C.<i> = ComplexField(20)
+            sage: C, i = ComplexField(20).objgen()
             sage: a = i^2; a
             -1.0000
@@ -278,17 +279,9 @@
         if isinstance(right, (int, long, integer.Integer)):
             return sage.rings.ring_element.RingElement.__pow__(self, right)
-        try:
-            P = self.parent()
-            right = P(right)
-            z = self._pari_()
-            w = P(right)._pari_()
-            m = z**w
-            return P(m)
-        except TypeError:
-            try:
-                self = right.parent()(self)
-                return self**right
-            except AttributeError:
-                raise TypeError
+        z = self._pari_()
+        P = (<ComplexNumber>self)._parent
+        w = P(right)._pari_()
+        m = z**w
+        return P(m)
     
     def prec(self):
@@ -355,5 +348,4 @@
 
         EXAMPLES:
-            sage: I = CC.0
             sage: a = ~(5+I)
             sage: a * (5+I)
@@ -424,5 +416,5 @@
 
         EXAMPLES:
-            sage: C.<i> = ComplexField()
+            sage: C, i = ComplexField().objgen()
             sage: i.multiplicative_order()
             4
@@ -437,5 +429,5 @@
             sage: C(2).multiplicative_order()
             +Infinity
-            sage: w = (1+sqrt(-3.0))/2; w
+            sage: w = (1+sqrt(-3))/2; w
             0.500000000000000 + 0.866025403784439*I
             sage: abs(w)
@@ -470,5 +462,5 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).acos()
+            sage: (1+I).acos()
             0.904556894302381 - 1.06127506190504*I
         """
@@ -478,5 +470,5 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).acosh()
+            sage: (1+I).acosh()
             1.06127506190504 + 0.904556894302381*I
         """
@@ -486,5 +478,5 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).asin()
+            sage: (1+I).asin()
             0.666239432492515 + 1.06127506190504*I
         """
@@ -494,5 +486,5 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).asinh()
+            sage: (1+I).asinh()
             1.06127506190504 + 0.666239432492515*I
         """
@@ -502,5 +494,5 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).atan()
+            sage: (1+I).atan()
             1.01722196789785 + 0.402359478108525*I
         """
@@ -510,38 +502,13 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).atanh()
+            sage: (1+I).atanh()
             0.402359478108525 + 1.01722196789785*I
         """
         return self._parent(self._pari_().atanh())
 
-    def coth(self):
-        """
-        EXAMPLES:
-            sage: ComplexField(100)(1,1).coth()
-            0.86801414289592494863584920892 - 0.21762156185440268136513424361*I
-        """
-        return 1/self.tanh()
-
-    def csch(self):
-        """
-        EXAMPLES:
-            sage: ComplexField(100)(1,1).csch()
-            0.30393100162842645033448560451 - 0.62151801717042842123490780586*I
-        """
-        return 1/self.sinh()
-
-    def sech(self):
-        """
-        EXAMPLES:
-            sage: ComplexField(100)(1,1).sech()
-            0.49833703055518678521380589177 - 0.59108384172104504805039169297*I            
-        """
-        return 1/self.cosh()
-    
-
     def cotan(self):
         """
         EXAMPLES:
-            sage: (1+CC(I)).cotan()
+            sage: (1+I).cotan()
             0.217621561854403 - 0.868014142895925*I
             sage: i = ComplexField(200).0
@@ -557,5 +524,5 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).cos()
+            sage: (1+I).cos()
             0.833730025131149 - 0.988897705762865*I
         """
@@ -565,5 +532,5 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).cosh()
+            sage: (1+I).cosh()
             0.833730025131149 + 0.988897705762865*I
         """
@@ -601,5 +568,4 @@
             sage: z = 1 + i; z.eta()
             0.742048775836565 + 0.198831370229911*I
-            sage: pi = CC(pi)        # otherwise we will get a symbolic result.
             sage: exp(pi * i * z / 12) * prod([1-exp(2*pi*i*n*z) for n in range(1,10)])
             0.742048775836565 + 0.198831370229911*I
@@ -624,5 +590,5 @@
 
         You can also use functional notation.
-            sage: eta(1+CC(I))
+            sage: eta(1+I)
             0.742048775836565 + 0.198831370229911*I
         """
@@ -636,5 +602,5 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).sin()
+            sage: (1+I).sin()
             1.29845758141598 + 0.634963914784736*I
         """
@@ -644,5 +610,5 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).sinh()
+            sage: (1+I).sinh()
             0.634963914784736 + 1.29845758141598*I
         """
@@ -652,5 +618,5 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).tan()
+            sage: (1+I).tan()
             0.271752585319512 + 1.08392332733869*I
         """
@@ -660,5 +626,5 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).tanh()
+            sage: (1+I).tanh()
             1.08392332733869 + 0.271752585319512*I
         """
@@ -669,5 +635,5 @@
         """
         EXAMPLES:
-            sage: (1+CC(I)).agm(2-I)
+            sage: (1+I).agm(2-I)
             1.62780548487271 + 0.136827548397369*I
         """
@@ -850,5 +816,5 @@
         EXAMPLE:
             sage: C = ComplexField()
-            sage: z = (1/2)*(1 + sqrt(3.0) *C.0); z
+            sage: z = (1/2)*(1 + sqrt(3) *C.0); z
             0.500000000000000 + 0.866025403784439*I
             sage: p = z.algdep(5); p
Index: sage/rings/contfrac.py
===================================================================
--- sage/rings/contfrac.py	(revision 4059)
+++ sage/rings/contfrac.py	(revision 3538)
@@ -626,8 +626,23 @@
         return s
 
-    def sqrt(self, bits=None):
+    def square_root(self):
+        """
+        Return exact square root or raise an error if self
+        is not a perfect square. 
+        
+        EXAMPLES:
+            sage: a = CFF(4/25).square_root(); a
+            [0, 2, 2]
+            sage: a.value()
+            2/5
+        """
+        return ContinuedFraction(self.parent(),
+                                 self._rational_().square_root())
+
+    def sqrt(self):
         """
         Return continued fraction approximation to the
-        square root of the value of this continued fraction.
+        square root of the value of this continued fraction, if
+        it is positive.  If self is negative raise a ValueError.
         
         EXAMPLES:
@@ -640,18 +655,9 @@
             sage: float(b.value()^2 - a)
             4.0935373134057017e-17
-            sage: a = CFF(4/25).sqrt(); a
-            [0, 2, 2]
-            sage: a.value()
-            2/5
         """
         r = self._rational_()
         if r < 0:
             raise ValueError, "self must be positive"
-        if bits is None:
-            if r.is_square():
-                return ContinuedFraction(self.parent(), r.sqrt())
-            else:
-                bits = 53
-        return ContinuedFraction(self.parent(), r.sqrt_approx(bits))
+        return ContinuedFraction(self.parent(), r.sqrt())
 
     def list(self):
@@ -758,7 +764,7 @@
         return self._rational_().is_one()
 
-    def __nonzero__(self):
-        """
-        Return False if self is zero.
+    def is_zero(self):
+        """
+        Return True if self is zero.
         
         EXAMPLES:
@@ -768,5 +774,5 @@
             False
         """
-        return not self._rational_().is_zero()
+        return self._rational_().is_zero()
 
     def _pari_(self):
Index: sage/rings/finite_field.py
===================================================================
--- sage/rings/finite_field.py	(revision 3991)
+++ sage/rings/finite_field.py	(revision 3125)
@@ -500,5 +500,4 @@
 
         Nonconstant polynomials do not coerce:
-            sage: x = polygen(QQ)
             sage: k(x)
             Traceback (most recent call last):
Index: sage/rings/finite_field_givaro.pyx
===================================================================
--- sage/rings/finite_field_givaro.pyx	(revision 4059)
+++ sage/rings/finite_field_givaro.pyx	(revision 3125)
@@ -1191,7 +1191,7 @@
         return (<FiniteField_givaro>self._parent)
 
-    def __nonzero__(FiniteField_givaroElement self):
+    def is_zero(FiniteField_givaroElement self):
         r"""
-        Return True if \code{self != k(0)}.
+        Return True if \code{self == k(0)}.
 
         EXAMPLES:
@@ -1203,5 +1203,5 @@
             True        
         """
-        return not bool((<FiniteField_givaro>self._parent).objectptr.isZero(self.element))
+        return bool((<FiniteField_givaro>self._parent).objectptr.isZero(self.element))
         
     def is_one(FiniteField_givaroElement self):
Index: sage/rings/fraction_field.py
===================================================================
--- sage/rings/fraction_field.py	(revision 4057)
+++ sage/rings/fraction_field.py	(revision 2399)
@@ -4,40 +4,4 @@
 AUTHOR: William Stein (with input from David Joyner, David Kohel, and
         Joe Wetherell)
-
-EXAMPLES:
-Quotienting is a constructor for an element of the fraction field:
-    sage: R.<x> = QQ[]
-    sage: (x^2-1)/(x+1)
-    x - 1
-    sage: parent((x^2-1)/(x+1))
-    Fraction Field of Univariate Polynomial Ring in x over Rational Field
-    
-
-The GCD is not taken (since it doesn't converge sometimes) in the inexact case.
-    sage: Z.<z> = CC[]
-    sage: I = CC.gen()
-    sage: (1+I+z)/(z+0.1*I)
-    (1.00000000000000*z + 1.00000000000000 + 1.00000000000000*I)/(1.00000000000000*z + 0.100000000000000*I)
-    sage: (1+I*z)/(z+1.1)
-    (1.00000000000000*I*z + 1.00000000000000)/(1.00000000000000*z + 1.10000000000000)
-    
-    
-TESTS:
-    sage: F = FractionField(IntegerRing())
-    sage: F == loads(dumps(F))
-    True
-    
-    sage: F = FractionField(PolynomialRing(RationalField(),'x'))
-    sage: F == loads(dumps(F))
-    True
-    
-    sage: F = FractionField(PolynomialRing(IntegerRing(),'x'))
-    sage: F == loads(dumps(F))
-    True
-
-    sage: F = FractionField(MPolynomialRing(RationalField(),2,'x'))
-    sage: F == loads(dumps(F))
-    True
-
 """
 
@@ -195,20 +159,5 @@
             R = self.ring()
             x = R(x); y = R(y)
-        return fraction_field_element.FractionFieldElement(self, x, y,
-                                            coerce=False, reduce = self.is_exact())
-
-    def is_exact(self):
-        """
-        EXAMPLES:
-            sage: Z.<z>=CC[]
-            sage: Z.is_exact()
-            False
-        """
-        try:
-            return self.__is_exact
-        except AttributeError:
-            r = self.ring().is_exact()
-            self.__is_exact = r
-        return r
+        return fraction_field_element.FractionFieldElement(self, x, y, coerce=False)
 
     def _coerce_impl(self, x):
Index: sage/rings/groebner_fan.py
===================================================================
--- sage/rings/groebner_fan.py	(revision 4007)
+++ sage/rings/groebner_fan.py	(revision 2487)
@@ -42,12 +42,4 @@
     sage: g.reduced_groebner_bases()
     [[1 - y^2 + x^2], [-1 + y^2 - x^2]]
-
-TESTS:
-    sage: x,y = QQ['x,y'].gens() 
-    sage: i = ideal(x^2 - y^2 + 1)
-    sage: g = i.groebner_fan()
-    sage: g == loads(dumps(g))
-    True
-
 """
 
@@ -127,7 +119,4 @@
         self.__ideal = I
         self.__ring = S
-
-    def __eq__(self,right):
-        return type(self) == type(right) and self.ideal() == right.ideal()
 
     def ideal(self):
Index: sage/rings/homset.py
===================================================================
--- sage/rings/homset.py	(revision 4057)
+++ sage/rings/homset.py	(revision 2369)
@@ -36,24 +36,4 @@
         return "Set of Homomorphisms from %s to %s"%(self.domain(), self.codomain())
 
-    def has_coerce_map_from(self, x):
-        """
-        The default for coercion maps between ring homomorphism
-        spaces is very restrictive (until more implementation work
-        is done).
-        """
-        return (x.domain() == self.domain() and x.codomain() == self.codomain())
-
-    def _coerce_impl(self, x):
-        if not isinstance(x, morphism.RingHomomorphism):
-            raise TypeError
-        if x.parent() is self:
-            return x
-        if x.parent() == self:
-            if isinstance(x, morphism.RingHomomorphism_im_gens):
-                return morphism.RingHomomorphism_im_gens(self, x.im_gens())
-            elif isinstance(x, morphism.RingHomomorphism_cover):
-                return morphism.RingHomomorphism_cover(self)
-        raise TypeError
-
     def __call__(self, im_gens, check=True):
         """
@@ -64,20 +44,9 @@
             ...
             TypeError: images do not define a valid homomorphism
-
-        TESTS:
-            sage: H = Hom(ZZ, QQ)
-            sage: H == loads(dumps(H))
-            True
         """
-        if isinstance(im_gens, (morphism.RingHomomorphism_im_gens,  morphism.RingHomomorphism_cover) ):
-            return self._coerce_impl(im_gens)
         try:
             return morphism.RingHomomorphism_im_gens(self, im_gens, check=check)
         except (NotImplementedError, ValueError), err:
-            try:
-                return self._coerce_impl(im_gens)
-            except TypeError:
-                raise TypeError, "images do not define a valid homomorphism"
-        
+            raise TypeError, "images do not define a valid homomorphism"
 
     def natural_map(self):
@@ -100,21 +69,6 @@
         sage: phi(b)
         a
-
-    TESTS:
-    We test pickling of a homset from a quotient. 
-        sage: R.<x,y> = PolynomialRing(QQ, 2)
-        sage: S.<a,b> = R.quotient(x^2 + y^2)
-        sage: H = S.Hom(R)
-        sage: H == loads(dumps(H))
-        True
-    
-    We test pickling of actual homomorphisms in a quotient:
-        sage: phi = S.hom([b,a])
-        sage: phi == loads(dumps(phi))
-        True
     """
     def __call__(self, im_gens, check=True):
-        if isinstance(im_gens, morphism.RingHomomorphism_from_quotient):
-            return morphism.RingHomomorphism_from_quotient(self, im_gens._phi())
         try:
             pi = self.domain().cover()
@@ -122,15 +76,5 @@
             return morphism.RingHomomorphism_from_quotient(self, phi)
         except (NotImplementedError, ValueError), err:
-            try:
-                return self._coerce_impl(im_gens)
-            except TypeError:
-                raise TypeError, "images do not define a valid homomorphism"
-
-    def _coerce_impl(self, x):
-        if not isinstance(x, morphism.RingHomomorphism_from_quotient):
-            raise TypeError
-        if x.parent() is self:
-            return x
-        if x.parent() == self:
-            return morphism.RingHomomorphism_from_quotient(self, x._phi())
-        raise TypeError
+            raise TypeError, "images do not define a valid homomorphism"
+    
+    
Index: sage/rings/ideal.py
===================================================================
--- sage/rings/ideal.py	(revision 4059)
+++ sage/rings/ideal.py	(revision 3311)
@@ -85,19 +85,4 @@
         ...
         TypeError: unable to find common ring into which all ideal generators map        
-
-    TESTS:
-        sage: R, x = PolynomialRing(ZZ, 'x').objgen()
-        sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2])
-        sage: I == loads(dumps(I))
-        True
-
-        sage: I = Ideal(R, [4 + 3*x + x^2, 1 + x^2])
-        sage: I == loads(dumps(I))
-        True
-                
-        sage: I = Ideal((4 + 3*x + x^2, 1 + x^2))
-        sage: I == loads(dumps(I))
-        True
-
     """
     if isinstance(R, Ideal_generic):
@@ -138,4 +123,5 @@
 
     gens = list(set(gens))
+
     if isinstance(R, sage.rings.principal_ideal_domain.PrincipalIdealDomain):
         # Use GCD algorithm to obtain a principal ideal
@@ -144,5 +130,5 @@
             g = R.gcd(g, h)
         return Ideal_pid(R, g)
-
+        
     if len(gens) == 1:
         return Ideal_principal(R, gens[0])
@@ -184,13 +170,9 @@
         return '(%s)'%(', '.join([str(x) for x in self.gens()]))
         
-    def __repr__(self):
+    def _repr_(self):
         return "Ideal %s of %s"%(self._repr_short(), self.ring())
 
     def __cmp__(self, other):
-        S = set(self.gens())
-        T = set(other.gens())
-        if S == T:
-            return 0
-        return cmp(self.gens(), other.gens())
+        return cmp(set(self.gens()), set(other.gens()))
 
     def __contains__(self, x):
@@ -204,6 +186,6 @@
         raise NotImplementedError
 
-    def __nonzero__(self):
-        return self.gens() != [self.ring()(0)]
+    def is_zero(self):
+        return self.gens() == [self.ring()(0)]
 
     def base_ring(self):
@@ -280,5 +262,5 @@
         Ideal_generic.__init__(self, ring, [gen])
 
-    def __repr__(self):
+    def _repr_(self):
         return "Principal ideal (%s) of %s"%(self.gen(), self.ring())
 
Index: sage/rings/ideal_monoid.py
===================================================================
--- sage/rings/ideal_monoid.py	(revision 4019)
+++ sage/rings/ideal_monoid.py	(revision 1851)
@@ -7,5 +7,4 @@
 from sage.structure.parent_gens import ParentWithGens
 import sage.rings.integer_ring
-import ideal
 
 def IdealMonoid(R):
@@ -26,13 +25,7 @@
 
     def __call__(self, x):
-        if isinstance(x, ideal.Ideal_generic):
-            x = x.gens()
         return self.__R.ideal(x)
 
     def _coerce_impl(self, x):
         R = self.__R
-        if isinstance(x, ideal.Ideal_generic):
-            x = [R._coerce_impl(y) for y in x.gens()]
-            return R.ideal(x)
-        else:
-            return R.ideal(R._coerce_(x))
+        return R.ideal(R._coerce_(x))
Index: sage/rings/infinity.py
===================================================================
--- sage/rings/infinity.py	(revision 4022)
+++ sage/rings/infinity.py	(revision 3335)
@@ -116,14 +116,4 @@
     ...
     SignError: cannot add positive finite value to negative finite value
-
-TESTS:
-    sage: P = InfinityRing
-    sage: P == loads(dumps(P))
-    True
-
-    sage: P(2) == loads(dumps(P(2)))
-    True
-
-
 """
 
@@ -271,7 +261,4 @@
     def _repr_(self):
         return "Infinity"
-
-    def _maxima_init_(self):
-        return "inf"
 
     def lcm(self, x):
@@ -481,12 +468,4 @@
         return "-Infinity"
 
-    def _maxima_init_(self):
-        """
-        EXAMPLES:
-            sage: maxima(-oo)
-            minf
-        """
-        return "minf"
-
     def _latex_(self):
         return "-\\infty"
@@ -558,12 +537,4 @@
         return "+Infinity"
 
-    def _maxima_init_(self):
-        """
-        EXAMPLES:
-            sage: maxima(oo)
-            inf
-        """
-        return "inf"
-
     def _latex_(self):
         return "+\\infty"
@@ -626,19 +597,18 @@
 infinity = InfinityRing.gen(0)
 Infinity = infinity
-minus_infinity = InfinityRing.gen(1)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: sage/rings/integer.pyx
===================================================================
--- sage/rings/integer.pyx	(revision 4065)
+++ sage/rings/integer.pyx	(revision 3666)
@@ -13,6 +13,4 @@
     -- Rishikesh (2007-02-25): changed quo_rem so that the rem is positive
     -- David Harvey, Martin Albrecht, Robert Bradshaw (2007-03-01): optimized Integer constructor and pool
-    -- Robert Bradshaw (2007-04-12): is_perfect_power, Jacobi symbol (with Kronecker extension)
-                                     Convert some methods to use GMP directly rather than pari, Integer() -> PY_NEW(Integer)
 
 EXAMPLES:
@@ -299,9 +297,9 @@
     def _xor(Integer self, Integer other):
         cdef Integer x
-        x = PY_NEW(Integer)
+        x = Integer()
         mpz_xor(x.value, self.value, other.value)
         return x
 
-    def __xor__(x, y):
+    def xor(x, y):
         """
         Compute the exclusive or of x and y.
@@ -309,5 +307,5 @@
         EXAMPLES:
             sage: n = ZZ(2); m = ZZ(3)
-            sage: n.__xor__(m)
+            sage: n.xor(m)
             1        
         """
@@ -316,4 +314,7 @@
         return bin_op(x, y, operator.xor)
         
+    def __xor__(self, right):
+        raise RuntimeError, "Use ** for exponentiation, not '^', which means xor\n"+\
+              "in Python, and has the wrong precedence.  Use x.xor(y) for the xor of x and y."
         
     def __richcmp__(left, right, int op):
@@ -339,5 +340,5 @@
         """
         cdef Integer z
-        z = PY_NEW(Integer)
+        z = Integer()
         set_mpz(z,self.value)
         return z
@@ -392,4 +393,5 @@
         Return the string representation of \code{self} in the given
         base.
+
 
         EXAMPLES:
@@ -617,6 +619,7 @@
     def __floordiv(Integer self, Integer other):
         cdef Integer x
-        x = PY_NEW(Integer)
-        
+        x = Integer()
+        
+
         _sig_on
         mpz_fdiv_q(x.value, self.value, other.value)
@@ -654,5 +657,8 @@
             1
             sage: (-1)^(1/3)
-            -1
+            Traceback (most recent call last):
+            ...
+            TypeError: exponent (=1/3) must be an integer.
+            Coerce your numbers to real or complex numbers first.
 
         The base need not be an integer (it can be a builtin
@@ -672,22 +678,4 @@
             RuntimeError: exponent must be at most 4294967294  # 32-bit
             RuntimeError: exponent must be at most 18446744073709551614 # 64-bit
-
-        We raise 2 to various interesting exponents:
-            sage: 2^x                # symbolic x
-            2^x
-            sage: 2^1.5              # real number
-            2.82842712474619 
-            sage: 2^I                # complex number
-            2^I
-            sage: f = 2^(sin(x)-cos(x)); f
-            2^(sin(x) - cos(x))
-            sage: f(3)
-            2^(sin(3) - cos(3))
-            sage: 2^(x+y+z)
-            2^(z + y + x)
-            sage: 2^(1/2)
-            sqrt(2)
-            sage: 2^(-1/2)
-            1/sqrt(2)
         """
         cdef Integer _n
@@ -704,9 +692,5 @@
             _n = Integer(n)
         except TypeError:
-            try:
-                s = n.parent()(self)
-                return s**n
-            except AttributeError:
-                raise TypeError, "exponent (=%s) must be an integer.\nCoerce your numbers to real or complex numbers first."%n
+            raise TypeError, "exponent (=%s) must be an integer.\nCoerce your numbers to real or complex numbers first."%n
 
         if _n < 0:
@@ -781,5 +765,5 @@
         cdef Integer x
         cdef int is_exact
-        x = PY_NEW(Integer)
+        x = Integer()
         _sig_on
         is_exact = mpz_root(x.value, self.value, n)
@@ -824,7 +808,7 @@
 
            sage: x = 3^100000
-           sage: RR(log(RR(x), 3))
+           sage: log(RR(x), 3)
            100000.000000000
-           sage: RR(log(RR(x + 100000), 3))
+           sage: log(RR(x + 100000), 3)
            100000.000000000
 
@@ -892,5 +876,5 @@
         """
         cdef Integer x
-        x = PY_NEW(Integer)
+        x = Integer()
         mpz_abs(x.value, self.value)
         return x
@@ -916,5 +900,5 @@
         
         cdef Integer x
-        x = PY_NEW(Integer)
+        x = Integer()
 
         _sig_on
@@ -955,6 +939,6 @@
 
         cdef Integer q, r
-        q = PY_NEW(Integer)
-        r = PY_NEW(Integer)
+        q = Integer()
+        r = Integer()
 
         _sig_on
@@ -995,6 +979,6 @@
 
         cdef Integer q, r
-        q = PY_NEW(Integer)
-        r = PY_NEW(Integer)
+        q = Integer()
+        r = Integer()
 
         _sig_on
@@ -1029,5 +1013,5 @@
             raise ZeroDivisionError, "cannot raise to a power modulo 0"
         
-        x = PY_NEW(Integer)
+        x = Integer()
 
         _sig_on
@@ -1071,5 +1055,5 @@
         cdef Integer x, _mod
         _mod = Integer(mod)
-        x = PY_NEW(Integer)
+        x = Integer()
 
         _sig_on
@@ -1084,4 +1068,7 @@
     def __long__(self):
         return mpz_get_pylong(self.value)
+
+    def __nonzero__(self):
+        return not self.is_zero()
 
     def __float__(self):
@@ -1226,5 +1213,5 @@
         
         cdef Integer z
-        z = PY_NEW(Integer)
+        z = Integer()
         mpz_set(z.value,x)
         mpz_clear(x)
@@ -1294,5 +1281,5 @@
         _sig_off
 
-        z = PY_NEW(Integer)
+        z = Integer()
         set_mpz(z, x)
         mpz_clear(x)
@@ -1333,7 +1320,7 @@
         return bool(mpz_cmp_si(self.value, 1) == 0)
 
-    def __nonzero__(self):
+    def is_zero(self):
         r"""
-        Returns \code{True} if the integers is not $0$, otherwise \code{False}.
+        Returns \code{True} if the integers is $0$, otherwise \code{False}.
 
         EXAMPLES:
@@ -1343,5 +1330,5 @@
             True
         """
-        return bool(mpz_cmp_si(self.value, 0) != 0)
+        return bool(mpz_cmp_si(self.value, 0) == 0)
 
     def is_unit(self):
@@ -1370,5 +1357,5 @@
             False
         """
-        return bool(mpz_perfect_square_p(self.value))
+        return bool(self._pari_().issquare())
 
     def is_prime(self):
@@ -1399,85 +1386,5 @@
         """
         return bool(self._pari_().ispseudoprime())
-        
-    def is_perfect_power(self):
-        r"""
-        Retuns \code{True} if self is a perfect power.
-
-        EXAMPLES:
-            sage: z = 8
-            sage: z.is_perfect_power()
-            True
-            sage: z = 144
-            sage: z.is_perfect_power()
-            True
-            sage: z = 10
-            sage: z.is_perfect_power()
-            False
-        """
-        return bool(mpz_perfect_power_p(self.value))
-        
-    def jacobi(self, b):
-        r"""
-        Calculate the Jacobi symbol $\left(\frac{self}{b}\right)$.
-
-        EXAMPLES:
-            sage: z = -1
-            sage: z.jacobi(17)
-            1
-            sage: z.jacobi(19)
-            -1
-            sage: z.jacobi(17*19)
-            -1
-            sage: (2).jacobi(17)
-            1
-            sage: (3).jacobi(19)
-            -1
-            sage: (6).jacobi(17*19)
-            -1
-            sage: (6).jacobi(33)
-            0
-            sage: a = 3; b = 7
-            sage: a.jacobi(b) == -b.jacobi(a)
-            True
-        """
-        cdef long tmp
-        if PY_TYPE_CHECK(b, int):
-            tmp = b
-            if (tmp & 1) == 0:
-                raise ValueError, "Jacobi symbol not defined for even b."
-            return mpz_kronecker_si(self.value, tmp)
-        if not PY_TYPE_CHECK(b, Integer):
-            b = Integer(b)
-        if mpz_even_p((<Integer>b).value):
-            raise ValueError, "Jacobi symbol not defined for even b."
-        return mpz_jacobi(self.value, (<Integer>b).value)
-        
-    def kronecker(self, b):
-        r"""
-        Calculate the Kronecker symbol
-        $\left(\frac{self}{b}\right)$ with the Kronecker extension 
-        $(self/2)=(2/self)$ when self odd, or $(self/2)=0$ when $self$ even.
-
-        EXAMPLES:
-        EXAMPLES:
-            sage: z = 5
-            sage: z.kronecker(41)
-            1
-            sage: z.kronecker(43)
-            -1
-            sage: z.kronecker(8)
-            -1
-            sage: z.kronecker(15)
-            0
-            sage: a = 2; b = 5
-            sage: a.kronecker(b) == b.kronecker(a)
-            True
-        """
-        if PY_TYPE_CHECK(b, int):
-            return mpz_kronecker_si(self.value, b)
-        if not PY_TYPE_CHECK(b, Integer):
-            b = Integer(b)
-        return mpz_kronecker(self.value, (<Integer>b).value)
-        
+
     def square_free_part(self):
         """
@@ -1636,5 +1543,5 @@
             raise ValueError, "square root of negative number not defined."
         cdef Integer x
-        x = PY_NEW(Integer)
+        x = Integer()
 
         _sig_on
@@ -1645,5 +1552,5 @@
 
     
-    def sqrt_approx(self, bits=None):
+    def sqrt(self, bits=None):
         r"""
         Returns the positive square root of self, possibly as a
@@ -1655,5 +1562,6 @@
                     If bits is not specified, the number of
                     bits of precision is at least twice the
-                    number of bits of self.
+                    number of bits of self (the precision
+                    is always at least 53 bits if not specified).
         OUTPUT:
             integer, real number, or complex number.
@@ -1664,28 +1572,30 @@
         EXAMPLE:
             sage: Z = IntegerRing()
-            sage: Z(4).sqrt_approx(53)
+            sage: Z(4).sqrt()
+            2
+            sage: Z(4).sqrt(53)
             2.00000000000000
-            sage: Z(2).sqrt_approx(53)
+            sage: Z(2).sqrt(53)
             1.41421356237310
-            sage: Z(2).sqrt_approx(100)
+            sage: Z(2).sqrt(100)
             1.4142135623730950488016887242
-            sage: n = 39188072418583779289; n.sqrt()
+            sage: n = 39188072418583779289; n.square_root()
             6260037733
-            sage: (100^100).sqrt_approx()
-            10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-            sage: (-1).sqrt_approx()
+            sage: (100^100).sqrt()
+            10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+            sage: (-1).sqrt()
             1.00000000000000*I
-            sage: (-1).sqrt()
-            I
             sage: sqrt(-2)
-            sqrt(2)*I
-            sage: sqrt(-2.0)
             1.41421356237310*I
             sage: sqrt(97)
-            sqrt(97)
-            sage: n = 97; n.sqrt_approx(200)
+            9.84885780179610
+            sage: n = 97; n.sqrt(200)
             9.8488578017961047217462114149176244816961362874427641717232
         """
         if bits is None:
+            try:
+                return self.square_root()
+            except ValueError:
+                pass
             bits = max(53, 2*(mpz_sizeinbase(self.value, 2)+2))
             
@@ -1699,5 +1609,5 @@
             return R(self).sqrt()
 
-    def sqrt(self):
+    def square_root(self):
         """
         Return the positive integer square root of self, or raises a ValueError
@@ -1705,18 +1615,15 @@
 
         EXAMPLES:
-            sage: Integer(144).sqrt()
+            sage: Integer(144).square_root()
             12
-            sage: Integer(102).sqrt()
-            sqrt(102)
-        """
-        if self < 0:
-            from sage.calculus.calculus import sqrt
-            return sqrt(self)
+            sage: Integer(102).square_root()
+            Traceback (most recent call last):
+            ...
+            ValueError: self (=102) is not a perfect square
+        """
         n = self.isqrt()
         if n * n == self:
             return n
-        from sage.calculus.calculus import sqrt
-        return sqrt(self)
-        #raise ValueError, "self (=%s) is not a perfect square"%self
+        raise ValueError, "self (=%s) is not a perfect square"%self
             
 
@@ -1747,7 +1654,7 @@
         _sig_off
         
-        g0 = PY_NEW(Integer)
-        s0 = PY_NEW(Integer)
-        t0 = PY_NEW(Integer)
+        g0 = Integer()
+        s0 = Integer()
+        t0 = Integer()
         set_mpz(g0,g)
         set_mpz(s0,s)
@@ -1842,5 +1749,5 @@
     cdef _and(Integer self, Integer other):
         cdef Integer x
-        x = PY_NEW(Integer)
+        x = Integer()
         mpz_and(x.value, self.value, other.value)
         return x
@@ -1854,5 +1761,5 @@
     cdef _or(Integer self, Integer other):
         cdef Integer x
-        x = PY_NEW(Integer)
+        x = Integer()
         mpz_ior(x.value, self.value, other.value)
         return x
@@ -1934,10 +1841,10 @@
         if r == 0:
             raise ZeroDivisionError, "Inverse does not exist."
-        ans = PY_NEW(Integer)
+        ans = Integer()
         set_mpz(ans,x)
         mpz_clear(x)
         return ans
         
-    def gcd(self, n):
+    def _gcd(self, Integer n):
         """
         Return the greatest common divisor of self and $n$.
@@ -1957,5 +1864,4 @@
         cdef mpz_t g
         cdef object g0
-        cdef Integer _n = Integer(n)
 
         mpz_init(g)
@@ -1963,8 +1869,8 @@
 
         _sig_on
-        mpz_gcd(g, self.value, _n.value)
+        mpz_gcd(g, self.value, n.value)
         _sig_off
 
-        g0 = PY_NEW(Integer)
+        g0 = Integer()
         set_mpz(g0,g)
         mpz_clear(g)
@@ -2039,5 +1945,5 @@
         
     
-    w = PY_NEW(Integer)
+    w = Integer()
     mpz_set(w.value, z)
     mpz_clear(z)
@@ -2082,5 +1988,5 @@
 
     
-    w = PY_NEW(Integer)
+    w = Integer()
     mpz_set(w.value, z)
     mpz_clear(z)
@@ -2356,5 +2262,5 @@
     PyObject_FREE(o)
 
-hook_fast_tp_functions()
+#hook_fast_tp_functions()
 
 def hook_fast_tp_functions():
Index: sage/rings/integer_mod.pxd
===================================================================
--- sage/rings/integer_mod.pxd	(revision 3924)
+++ sage/rings/integer_mod.pxd	(revision 3357)
@@ -14,6 +14,5 @@
     cdef int_fast32_t int32
     cdef int_fast64_t int64
-    cdef object table # a list
-    cdef object inverses # also a list
+    cdef object table # how much faster is unsafe access to a list than a c array?
     cdef lookup(NativeIntStruct self, Py_ssize_t value)
 
@@ -21,11 +20,8 @@
 cdef class IntegerMod_abstract(sage.structure.element.CommutativeRingElement):
     cdef NativeIntStruct __modulus
-    cdef _new_c_from_long(self, long value)
-    cdef void set_from_mpz(self, mpz_t value)
-    cdef void set_from_long(self, long value)
-    cdef int is_square_c(self) except -2
 
 cdef class IntegerMod_gmp(IntegerMod_abstract):
     cdef mpz_t value
+    cdef void set_from_mpz(IntegerMod_gmp self, mpz_t value)
     cdef mpz_t* get_value(IntegerMod_gmp self)
     cdef IntegerMod_gmp _new_c(self)    
@@ -33,4 +29,5 @@
 cdef class IntegerMod_int(IntegerMod_abstract):
     cdef public int_fast32_t ivalue
+    cdef void set_from_mpz(IntegerMod_int self, mpz_t value)
     cdef void set_from_int(IntegerMod_int self, int_fast32_t value)
     cdef int_fast32_t get_int_value(IntegerMod_int self)
@@ -39,4 +36,5 @@
 cdef class IntegerMod_int64(IntegerMod_abstract):
     cdef int_fast64_t ivalue
+    cdef void set_from_mpz(IntegerMod_int64 self, mpz_t value)
     cdef void set_from_int(IntegerMod_int64 self, int_fast64_t value)
     cdef int_fast64_t get_int_value(IntegerMod_int64 self)
Index: sage/rings/integer_mod.pyx
===================================================================
--- sage/rings/integer_mod.pyx	(revision 4065)
+++ sage/rings/integer_mod.pyx	(revision 3598)
@@ -4,22 +4,8 @@
 An element of the integers modulo $n$.
 
-There are three types of integer_mod classes, depending on the 
-size of the modulus. The range is capped such that a single 
-arithmetic operation (e.g. multiplication) will not overflow. 
-
-- IntegerMod_int stores its value in a int_fast32_t (typically an int)
-- IntegerMod_int64 stores its value in a int_fast64_t (typically a long long)
-- IntegerMod_gmp stores its value in a mpz_t
-   
-All extend IntegerMod_abstract. 
-
-For efficency reasons, it stores the modulus (in all three forms, if possible) in a common (cdef) class NativeIntStruct rather than in the parent. 
-
-
 AUTHORS:
     -- Robert Bradshaw (most of the work)
     -- Didier Deshommes (bit shifting)
     -- William Stein (editing and polishing; new arith architecture)
-    -- Robert Bradshaw (implement native is_square and square_root)
 
 TESTS:
@@ -30,20 +16,6 @@
 """
 
-#################################################################################
-#       Copyright (C) 2006 Robert Bradshaw <robertwb@math.washington.edu>
-#                     2006 William Stein <wstein@gmail.com>
-#
-#  Distributed under the terms of the GNU General Public License (GPL)
-#
-#                  http://www.gnu.org/licenses/
-#*****************************************************************************
-
-
 include "../ext/interrupt.pxi"  # ctrl-c interrupt block support
 include "../ext/stdsage.pxi"
-
-cdef extern from "math.h":
-    double log(double)
-    int ceil(double)
 
 import operator
@@ -135,11 +107,5 @@
     
 cdef class NativeIntStruct:
-    """
-    We store the various forms of the modulus here rather than in the 
-    parent for efficiency reasons. 
-    
-    We may also store a cached table of all elements of a given 
-    ring in this class.  
-    """
+
     def __init__(NativeIntStruct self, sage.rings.integer.Integer z):
         self.int64 = -1
@@ -155,5 +121,5 @@
         return sage.rings.integer_mod.makeNativeIntStruct, (self.sageInteger, )
         
-    def precompute_table(NativeIntStruct self, parent, inverses=True):
+    def precompute_table(NativeIntStruct self, parent):
         self.table = PyList_New(self.int64)
         cdef Py_ssize_t i
@@ -166,13 +132,4 @@
                 z = IntegerMod_int64(parent, i)
                 Py_INCREF(z); PyList_SET_ITEM(self.table, i, z)
-                
-        if inverses:
-            tmp = [None] * self.int64
-            for i from 1 <= i < self.int64:
-                try:
-                    tmp[i] = ~self.table[i]
-                except ZeroDivisionError:
-                    pass
-            self.inverses = tmp
 
     cdef lookup(NativeIntStruct self, Py_ssize_t value):
@@ -192,21 +149,4 @@
         self._parent = parent
         self.__modulus = parent._pyx_order
-        
-        
-    cdef _new_c_from_long(self, long value):
-        cdef IntegerMod_abstract x
-        x = <IntegerMod_abstract>PY_NEW(<object>PY_TYPE(self))
-        if PY_TYPE_CHECK(x, IntegerMod_gmp):
-            mpz_init((<IntegerMod_gmp>x).value) # should be done by the new method
-        x._parent = self._parent
-        x.__modulus = self.__modulus
-        x.set_from_long(value)
-        return x
-
-    cdef void set_from_mpz(self, mpz_t value):
-        raise NotImplementedError, "Must be defined in child class."
-
-    cdef void set_from_long(self, long value):
-        raise NotImplementedError, "Must be defined in child class."
 
     def __abs__(self):
@@ -418,4 +358,15 @@
         """
         return self.__modulus.sageInteger
+        
+    
+    def is_square(self):
+        """
+        EXAMPLES:
+            sage: Mod(3,17).is_square()
+            False
+            sage: Mod(9,17).is_square()
+            True
+        """
+        return bool(self.pari().issquare()) 
 
     def charpoly(self, var):
@@ -470,70 +421,4 @@
         return self
 
-
-    def is_square(self):
-        r"""
-        EXAMPLES:
-            sage: Mod(3,17).is_square()
-            False
-            sage: Mod(9,17).is_square()
-            True
-            sage: Mod(9,17*19^2).is_square()
-            True
-            sage: Mod(-1,17^30).is_square()
-            True
-            sage: Mod(1/9, next_prime(2^40)).is_square()
-            True
-            sage: Mod(1/25, next_prime(2^90)).is_square()
-            True
-            
-        TESTS: 
-            sage: Mod(1/25, 2^8).is_square()
-            True
-            sage: Mod(1/25, 2^40).is_square()
-            True
-            
-        ALGORITHM:
-            Calculate the Jacobi symbol $(self/p)$ at each prime $p$ dividing $n$
-            It must be 1 or 0 for each prime, and if it is 0 mod $p$, 
-            where $p^k || n$, then $ord_p(self)$ must be even or greater than $k$. 
-            
-            $p = 2$ handled seperatly.
-            
-        AUTHOR: 
-            -- Robert Bradshaw
-        """
-        return bool(self.is_square_c())
-    
-    cdef int is_square_c(self) except -2:
-        if self.is_zero() or self.is_one():
-            return 1
-        moduli = self.parent().factored_order()
-        cdef int val, e
-        lift = self.lift()
-        if len(moduli) == 1:
-            p, e = moduli[0]
-            if e == 1:
-                return lift.jacobi(p) != -1
-            elif p == 2:
-                return self.pari().issquare() # TODO: implement directly
-            elif self % p == 0:
-                val = lift.valuation(p)
-                return val >= e or (val % 2 == 0 and (lift // p**val).jacobi(p) != -1)
-            else:
-                return lift.jacobi(p) != -1
-        else:
-            for p, e in moduli:
-                if p == 2:
-                    if e > 1 and not self.pari().issquare(): # TODO: implement directly
-                        return 0
-                elif e > 1 and lift % p == 0:
-                    val = lift.valuation(p)
-                    if val < e and (val % 2 == 1 or (lift // p**val).jacobi(p) == -1):
-                        return 0
-                elif lift.jacobi(p) == -1:
-                    return 0
-            return 1
-
-
     def sqrt(self):
         """
@@ -541,15 +426,7 @@
         """
         return self.square_root()
-        
 
     def square_root(self):
         """
-        Calculates the square roots mod $p$ for each of the primes $p$ dividing 
-        the order of the ring, then lifts p-adically and uses crt to 
-        find a square root mod $n$. 
-        
-        See also \code{square_root_mod_prime_power} and \code{square_root_mod_prime}
-        (in this module) algorithms details. 
-        
         EXAMPLES: 
             sage: mod(-1, 17).square_root()
@@ -557,58 +434,9 @@
             sage: mod(5, 389).square_root()
             86
-            sage: mod(7, 18).square_root()
-            5
-            sage: a = mod(14, 5^60).square_root()
-            sage: a*a
-            14            
-            sage: mod(15, 389).square_root()
-            Traceback (most recent call last):
-            ...
-            ValueError: Self must be a square.
-            sage: Mod(1/9, next_prime(2^40)).square_root()^(-2)
-            9
-            sage: Mod(1/25, next_prime(2^90)).square_root()^(-2)
-            25
-
-        """ 
-        if self.is_zero() or self.is_one():
-            return self
-            
-        if not self.is_square_c():
-            raise ValueError, "Self must be a square."
-            
-        moduli = self._parent.factored_order()
-        if len(moduli) == 1:
-            p, e = moduli[0]
-            if e > 1:
-                x = square_root_mod_prime_power(mod(self, p**e), p, e)
-            else:
-                x = square_root_mod_prime(self, p)
-                
-        else:
-            # return product of square roots mod each prime power
-            sqrts = [square_root_mod_prime(mod(self, p), p) for p, e in moduli if e == 1] + \
-                    [square_root_mod_prime_power(mod(self, p**e), p, e) for p, e in moduli if e != 1]
-            
-            x = sqrts.pop()
-            for y in sqrts:
-                x = x.crt(y)
-        
-        return x._balanced_abs()
-        
-    def _balanced_abs(self):
-        """
-        This function returns x or -x, whichever has a positive
-        representative in -p/2 < x < p/2.
-        
-        This is used so that the same square root is always returned, 
-        despite the possibly probabalistic nature of the underlying 
-        algorithm. 
-        """
-        if self.lift() > self.__modulus.sageInteger >> 1:
-            return -self
-        else:
-            return self
-
+        """
+        try:
+            return self.parent()(self.pari().sqrt())  # TODO: implement directly
+        except PariError:
+            raise ValueError, "self must be a square."
         
     def rational_reconstruction(self):
@@ -746,11 +574,8 @@
             return
         cdef sage.rings.integer.Integer z
-        if PY_TYPE_CHECK(value, sage.rings.integer.Integer):
+        if isinstance(value, sage.rings.integer.Integer):
             z = value
-        elif PY_TYPE_CHECK(value, rational.Rational):
+        elif isinstance(value, rational.Rational):
             z = value % self.__modulus.sageInteger
-        elif PY_TYPE_CHECK(value, int):
-            self.set_from_long(value)
-            return
         else:
             z = sage.rings.integer_ring.Z(value)
@@ -768,5 +593,5 @@
         mpz_clear(self.value)
 
-    cdef void set_from_mpz(self, mpz_t value):
+    cdef void set_from_mpz(IntegerMod_gmp self, mpz_t value):
         cdef sage.rings.integer.Integer modulus
         modulus = self.__modulus.sageInteger
@@ -775,10 +600,4 @@
         else:
             mpz_set(self.value, value)
-
-    cdef void set_from_long(self, long value):
-        cdef sage.rings.integer.Integer modulus
-        mpz_set_si(self.value, value)
-        if value < 0 or mpz_cmp_si(self.__modulus.sageInteger.value, value) >= 0:
-            mpz_mod(self.value, self.value, self.__modulus.sageInteger.value)
         
     cdef mpz_t* get_value(IntegerMod_gmp self):
@@ -825,5 +644,5 @@
     def is_one(IntegerMod_gmp self):
         """
-        Returns \code{True} if this is $1$, otherwise \code{False}.
+        Returns \\code{True} if this is $1$, otherwise \\code{False}.
 
         EXAMPLES:
@@ -835,7 +654,7 @@
         return bool(mpz_cmp_si(self.value, 1) == 0)
 
-    def __nonzero__(IntegerMod_gmp self):
-        """
-        Returns \code{True} if this is not $0$, otherwise \code{False}.
+    def is_zero(IntegerMod_gmp self):
+        """
+        Returns \\code{True} if this is $0$, otherwise \\code{False}.
 
         EXAMPLES:
@@ -845,5 +664,5 @@
             True
         """
-        return bool(mpz_cmp_si(self.value, 0) != 0)
+        return bool(mpz_cmp_si(self.value, 0) == 0)
 
     def is_unit(self):
@@ -959,7 +778,8 @@
 
     def __mod__(self, right):
+        right = int(right)
         if self.modulus() % right != 0:
             raise ZeroDivisionError, "Error - reduction modulo right not defined."
-        return IntegerMod(integer_mod_ring.IntegerModRing(right), self)
+        return IntegerMod(integer_mod_ring.IntegerModRing(right, self))
     
     def __pow__(IntegerMod_gmp self, right, m): # NOTE: m ignored, always use modulus of parent ring
@@ -1095,5 +915,6 @@
         if self.__modulus.table is not None:
             return self.__modulus.lookup(value)
-        cdef IntegerMod_int x = PY_NEW(IntegerMod_int)
+        cdef IntegerMod_int x
+        x = PY_NEW(IntegerMod_int)
         x.__modulus = self.__modulus
         x._parent = self._parent
@@ -1101,5 +922,5 @@
         return x
 
-    cdef void set_from_mpz(self, mpz_t value):
+    cdef void set_from_mpz(IntegerMod_int self, mpz_t value):
         if mpz_sgn(value) == -1 or mpz_cmp_si(value, self.__modulus.int32) >= 0:
             self.ivalue = mpz_fdiv_ui(value, self.__modulus.int32)
@@ -1107,7 +928,4 @@
             self.ivalue = mpz_get_si(value)
             
-    cdef void set_from_long(self, long value):
-        self.ivalue = value % self.__modulus.int32
-
     cdef void set_from_int(IntegerMod_int self, int_fast32_t ivalue):
         if ivalue < 0:
@@ -1150,5 +968,5 @@
     def is_one(IntegerMod_int self):
         """
-        Returns \code{True} if this is $1$, otherwise \code{False}.
+        Returns \\code{True} if this is $1$, otherwise \\code{False}.
 
         EXAMPLES:
@@ -1160,7 +978,7 @@
         return bool(self.ivalue == 1)
 
-    def __nonzero__(IntegerMod_int self):
-        """
-        Returns \code{True} if this is not $0$, otherwise \code{False}.
+    def is_zero(IntegerMod_int self):
+        """
+        Returns \\code{True} if this is $0$, otherwise \\code{False}.
 
         EXAMPLES:
@@ -1170,5 +988,5 @@
             True
         """
-        return bool(self.ivalue != 0)
+        return bool(self.ivalue == 0)
 
     def is_unit(IntegerMod_int self):
@@ -1260,14 +1078,8 @@
             4
         """
-        if self.__modulus.inverses is not None:
-            right_inverse = self.__modulus.inverses[(<IntegerMod_int>right).ivalue]
-            if right_inverse is None:
-                raise ZeroDivisionError, "Inverse does not exist."
-            else:
-                return self._new_c((self.ivalue * (<IntegerMod_int>right_inverse).ivalue) % self.__modulus.int32)
-                
         cdef int_fast32_t x
-        x = self.ivalue * mod_inverse_int((<IntegerMod_int>right).ivalue, self.__modulus.int32)
-        return self._new_c(x% self.__modulus.int32)
+        x = (self.ivalue * mod_inverse_int(
+            (<IntegerMod_int>right).ivalue, self.__modulus.int32) ) % self.__modulus.int32
+        return self._new_c(x)
             
     def __int__(IntegerMod_int self):
@@ -1305,5 +1117,8 @@
             160
         """
-        return self._new_c((self.ivalue << right) % self.__modulus.int32)
+        cdef IntegerMod_int x
+        x = IntegerMod_int(self._parent, None, empty=True)
+        x.ivalue = (self.ivalue << right) % self.__modulus.int32
+        return x
 
     def __rshift__(IntegerMod_int self, int right):
@@ -1318,5 +1133,8 @@
             1
         """
-        return self._new_c(self.ivalue >> right)
+        cdef IntegerMod_int x
+        x = IntegerMod_int(self._parent, None, empty=True)
+        x.ivalue = (self.ivalue >> right) % self.__modulus.int32
+        return x
     
     def __pow__(IntegerMod_int self, right, m): # NOTE: m ignored, always use modulus of parent ring
@@ -1355,12 +1173,5 @@
             43
         """
-        if self.__modulus.inverses is not None:
-            x = self.__modulus.inverses[self.ivalue]
-            if x is None:
-                raise ZeroDivisionError, "Inverse does not exist."
-            else:
-                return x
-        else:
-            return self._new_c(mod_inverse_int(self.ivalue, self.__modulus.int32))
+        return self._new_c(mod_inverse_int(self.ivalue, self.__modulus.int32))
 
     def lift(IntegerMod_int self):
@@ -1382,5 +1193,5 @@
     
     def __float__(IntegerMod_int self):
-        return <double>self.ivalue
+        return float(self.ivalue)
 
     def __hash__(self):
@@ -1392,48 +1203,4 @@
         """
         return hash(self.ivalue)
-        
-    cdef int is_square_c(self) except -2:
-        if self.ivalue <= 1:
-            return 1
-        moduli = self._parent.factored_order()
-        cdef int val, e
-        cdef int_fast32_t p
-        if len(moduli) == 1:
-            sage_p, e = moduli[0]
-            p = sage_p
-            if e == 1:
-                return jacobi_int(self.ivalue, p) != -1
-            elif p == 2:
-                return self.pari().issquare() # TODO: implement directly
-            elif self.ivalue % p == 0:
-                val = self.lift().valuation(sage_p)
-                return val >= e or (val % 2 == 0 and jacobi_int(self.ivalue / int(sage_p**val), p) != -1)
-            else:
-                return jacobi_int(self.ivalue, p) != -1
-        else:
-            for sage_p, e in moduli:
-                p = sage_p
-                if p == 2:
-                    if e > 1 and not self.pari().issquare(): # TODO: implement directly
-                        return 0
-                elif e > 1 and self.ivalue % p == 0:
-                    val = self.lift().valuation(sage_p)
-                    if val < e and (val % 2 == 1 or jacobi_int(self.ivalue / int(sage_p**val), p) == -1):
-                        return 0
-                elif jacobi_int(self.ivalue, p) == -1:
-                    return 0
-            return 1
-            
-    def _balanced_abs(self):
-        """
-        This function returns x or -x, whichever has a positive
-        representative in -p/2 < x < p/2.
-        """
-        if self.ivalue > self.__modulus.int32 / 2:
-            return -self
-        else:
-            return self
-
-        
 
 ### End of class
@@ -1521,41 +1288,4 @@
     
 
-cdef int jacobi_int(int_fast32_t a, int_fast32_t m) except -2:
-    """
-    Calculates the jacobi symbol (a/n)
-    For use in IntegerMod_int
-    AUTHOR: 
-      -- Robert Bradshaw
-    """
-    cdef int s, jacobi = 1
-    cdef int_fast32_t b
-
-    a = a % m
-    
-    while 1:
-        if a == 0:
-            return 0 # gcd was nontrivial
-        elif a == 1:
-            return jacobi
-        s = 0
-        while (1 << s) & a == 0:
-            s += 1
-        b = a >> s
-        # Now a = 2^s * b
-        
-        # factor out (2/m)^s term
-        if s % 2 == 1 and (m % 8 == 3 or m % 8 == 5):
-            jacobi = -jacobi
-            
-        if b == 1:
-            return jacobi
-            
-        # quadratic reciprocity
-        if b % 4 == 3 and m % 4 == 3:
-            jacobi = -jacobi
-        a = m % b
-        m = b
-
-
 def test_gcd(a, b):
     return gcd_int(int(a), int(b))
@@ -1616,13 +1346,10 @@
         return x
     
-    cdef void set_from_mpz(self, mpz_t value):
+    cdef void set_from_mpz(IntegerMod_int64 self, mpz_t value):
         if mpz_sgn(value) == -1 or mpz_cmp_si(value, self.__modulus.int64) >= 0:
             self.ivalue = mpz_fdiv_ui(value, self.__modulus.int64)
         else:
             self.ivalue = mpz_get_si(value)
-    
-    cdef void set_from_long(self, long value):
-        self.ivalue = value % self.__modulus.int64
-                    
+            
     cdef void set_from_int(IntegerMod_int64 self, int_fast64_t ivalue):
         if ivalue < 0:
@@ -1661,5 +1388,5 @@
     def is_one(IntegerMod_int64 self):
         """
-        Returns \code{True} if this is $1$, otherwise \code{False}.
+        Returns \\code{True} if this is $1$, otherwise \\code{False}.
 
         EXAMPLES:
@@ -1671,7 +1398,7 @@
         return bool(self.ivalue == 1)
 
-    def __nonzero__(IntegerMod_int64 self):
-        """
-        Returns \code{True} if this is not $0$, otherwise \code{False}.
+    def is_zero(IntegerMod_int64 self):
+        """
+        Returns \\code{True} if this is $0$, otherwise \\code{False}.
 
         EXAMPLES:
@@ -1681,5 +1408,5 @@
             True
         """
-        return bool(self.ivalue != 0)
+        return bool(self.ivalue == 0)
 
     def is_unit(IntegerMod_int64 self):
@@ -1844,5 +1571,5 @@
             1
         """
-        return self._new_c(self.ivalue >> right)
+        return self._new_c((self.ivalue >> right) % self.__modulus.int64)
 
     def __invert__(IntegerMod_int64 self):
@@ -1886,5 +1613,5 @@
             8943.0
         """
-        return <double>self.ivalue
+        return float(self.ivalue)
 
     def __hash__(self):
@@ -1902,15 +1629,4 @@
         
         return hash(self.ivalue)
-            
-    def _balanced_abs(self):
-        """
-        This function returns x or -x, whichever has a positive
-        representative in -p/2 < x < p/2.
-        """
-        if self.ivalue > self.__modulus.int64 / 2:
-            return -self
-        else:
-            return self
-
 
 ### End of class
@@ -1987,8 +1703,8 @@
     while(exp != 0):
         pow2 = pow2 * pow2
-        if pow2 >= INTEGER_MOD_INT64_LIMIT: pow2 = pow2 % n
+        if pow2 >= INTEGER_MOD_INT32_LIMIT: pow2 = pow2 % n
         if exp % 2:
             prod = prod * pow2
-            if prod >= INTEGER_MOD_INT64_LIMIT: prod = prod % n
+            if prod >= INTEGER_MOD_INT32_LIMIT: prod = prod % n
         exp = exp >> 1
         
@@ -1996,230 +1712,2 @@
         prod = prod % n
     return prod
-    
-
-cdef int jacobi_int64(int_fast64_t a, int_fast64_t m) except -2:
-    """
-    Calculates the jacobi symbol (a/n)
-    For use in IntegerMod_int64
-    AUTHOR: 
-      -- Robert Bradshaw
-    """
-    cdef int s, jacobi = 1
-    cdef int_fast64_t b
-
-    a = a % m
-    
-    while 1:
-        if a == 0:
-            return 0 # gcd was nontrivial
-        elif a == 1:
-            return jacobi
-        s = 0
-        while (1 << s) & a == 0:
-            s += 1
-        b = a >> s
-        # Now a = 2^s * b
-        
-        # factor out (2/m)^s term
-        if s % 2 == 1 and (m % 8 == 3 or m % 8 == 5):
-            jacobi = -jacobi
-            
-        if b == 1:
-            return jacobi
-            
-        # quadratic reciprocity
-        if b % 4 == 3 and m % 4 == 3:
-            jacobi = -jacobi
-        a = m % b
-        m = b
-
-
-########################
-# Square root functions
-########################
-
-def square_root_mod_prime_power(IntegerMod_abstract a, p, e):
-    r"""
-    Calculates the square root of $a$, where $a$ is an integer mod $p^e$.
-    
-    ALGORITHM: 
-        Perform p-adically by stripping off even powers of $p$ to get
-        a unit and lifting $\sqrt{unit} mod p$ via newton's method.
-        
-    AUTHOR:
-        -- Robert Bradshaw
-    """
-    if a.is_zero() or a.is_one():
-        return a
-    
-    if p == 2:
-        return a if e == 1 else self.parent()(self.pari().sqrt())  # TODO: implement directly
-    
-    # strip off even powers of p
-    cdef int i, val = a.lift().valuation(p)
-    if val % 2 == 1:
-        raise ValueError, "self must be a square."
-    if val > 0:
-        unit = a._parent(a.lift() // p**val)
-    else:
-        unit = a
-        
-    # find square root of unit mod p
-    x = unit.parent()(square_root_mod_prime(mod(unit, p), p))
-
-    # lift p-adically using newton iteration
-    # this is done to higher precision than neccisary except at the last step
-    one_half = ~(a._new_c_from_long(2))
-    for i from 0 <= i <  ceil(log(e)/log(2)) - val/2:
-        x = (x+unit/x) * one_half
-    
-    # multiply in powers of p (if any)
-    if val > 0:
-        x *= p**(val // 2)
-    return x
-    
-def square_root_mod_prime(IntegerMod_abstract a, p=None):
-    r"""
-    Calculates the square root of a, where a is an integer mod p. 
-    
-    ALGORITHM: 
-        Several cases based on residue class of p mod 16.
-        
-        $p$ mod 2 = 0 $\Rightarrow$ p = 2 so \sqrt{a} = a$.
-        $p$ mod 4 = 3 $\Rightarrow \sqrt{a} = a^{(p+1)/4}$.
-        $p$ mod 8 = 5 $\Rightarrow \sqrt{a} = \zeta i a$ where $\zeta = (2a)^{(p-5)/8}$, $i=\sqrt{-1}$.
-        $p$ mod 16 = 9$ Similar, work in a bi-quadratic extension of $\FF_p$.
-        $p$ mod 16 = 1$ Variant of Cipolla-Lehmer, using Lucas functions.
-        
-    REFERENCES: 
-        Siguna M\:uller. 'On the Computation of Square Roots in Finite Fields'
-            Designs, Codes and Cryptography, Volume 31,  Issue 3 (March 2004)
-            
-        A. Oliver L. Atkin. 'Probabilistic primality testing' (Section 4)
-            In P. Flajolet and P. Zimmermann, editors, Analysis of Algorithms Seminar I. INRIA Research Report XXX, 1992. 
-            Summary by F. Morain. 
-            \url{http://citeseer.ist.psu.edu/atkin92probabilistic.html}
-            
-        H. Postl. 'Fast evaluation of Dickson Polynomials'
-            Contrib. to General Algebra, Vol. 6 (1988) pp. 223--225
-        
-    AUTHOR:
-        Robert Bradshaw
-        
-    TESTS: 
-        Every case appears in the first hundred primes. 
-        sage: all([(a*a).square_root()^2 == a*a for p in prime_range(100) for a in Integers(p)])
-        True
-    """
-    if a.is_zero() or a.is_one():
-        return a
-    
-    if p is None:
-        p = a.parent().order()
-    if p < PyInt_GetMax():
-        p = int(p)
-
-    cdef int p_mod_16 = p % 16
-    
-    if p_mod_16 % 2 == 0:  # p == 2
-        return a
-        
-    elif p_mod_16 % 4 == 3:
-        return a ** ((p+1)/4)
-        
-    elif p_mod_16 % 8 == 5:
-        two_a = a+a
-        zeta = two_a ** ((p-5)/8)
-        i = two_a ** ((p-1)/4)
-        return zeta*a*(i-1)
-        
-    elif p_mod_16 == 9:
-        s = (a+a) ** ((p-1)/4)
-        if s.is_one():
-            d = a._parent.quadratic_nonresidue()
-            d2 = d*d
-            z = (2 * d2 * a) ** ((p-9)/16)
-            i = 2 * d2 * z*z * a
-            return z*d*a*(i-1)
-        else:
-            z = (a+a) ** ((p-9)/16)
-            i = 2 * z*z * a
-            return z*a*(i-1)
-            
-    else: # p_mod_16 == 1
-
-        four = a._new_c_from_long(4)
-        
-        if a == four:
-            return a._new_c_from_long(2)
-            
-        if not (<IntegerMod_abstract>(a - four)).is_square_c():
-            t = 1
-            P = a - 2
-            return fast_lucas((p-1) // 4, P)
-            
-        else:
-            t = a._new_c_from_long(2)
-            while (<IntegerMod_abstract>(a*t*t - four)).is_square_c():
-                t += 1
-            P = a*t*t - 2
-            return fast_lucas((p-1)//4, P)/t
-        
-        
-def fast_lucas(mm, IntegerMod_abstract P):
-    """
-    Return $V_k(P, 1)$ where $V_k$ is the Lucas function 
-    defined by the recursive relation
-
-    $V_k(P, Q) = PV_{k-1}(P, Q) -  QV_{k-2}(P, Q)$
-    
-    with $V_0 = 2, V_1(P_Q) = P$.
-    
-    REFERENCES: 
-        H. Postl. 'Fast evaluation of Dickson Polynomials'
-            Contrib. to General Algebra, Vol. 6 (1988) pp. 223\202\304\354225
-        
-    AUTHOR: 
-        Robert Bradshaw
-        
-    TESTS:
-        sage: from sage.rings.integer_mod import fast_lucas, slow_lucas
-        sage: all([fast_lucas(k, a) == slow_lucas(k, a) for a in Integers(23) for k in range(13)])
-        True
-    """
-    if mm == 0:
-        return 2
-    elif mm == 1:
-        return P
-
-    cdef sage.rings.integer.Integer m
-    m = <sage.rings.integer.Integer>mm if PY_TYPE_CHECK(mm, sage.rings.integer.Integer) else sage.rings.integer.Integer(mm)
-    two = P._new_c_from_long(2)
-    d1 = P
-    d2 = P*P - two
-    
-    _sig_on
-    cdef int j
-    for j from mpz_sizeinbase(m.value, 2)-1 > j > 0:
-        if mpz_tstbit(m.value, j):
-            d1 = d1*d2 - P
-            d2 = d2*d2 - two
-        else:
-            d2 = d1*d2 - P
-            d1 = d1*d1 - two
-    _sig_off
-    if mpz_odd_p(m.value):
-        return d1*d2 - P
-    else:
-        return d1*d1 - two
-        
-def slow_lucas(k, P, Q=1):
-    """
-    Lucas function defined using the definition, for consitancy testing. 
-    """
-    if k == 0:
-        return 2
-    elif k == 1:
-        return P
-    else:
-        return P*slow_lucas(k-1, P, Q) - Q*slow_lucas(k-2, P, Q)
Index: sage/rings/integer_mod_ring.py
===================================================================
--- sage/rings/integer_mod_ring.py	(revision 3925)
+++ sage/rings/integer_mod_ring.py	(revision 3524)
@@ -340,21 +340,16 @@
         if arith.is_prime(n):
             return True
-
+        
         # TODO -- the implementation below uses factoring, but it doesn't
         # need to; really it just needs to know if n is a prime power or not,
         # which is easier than factoring. 
     
-        if n.is_perfect_power():
-            F = arith.factor(n)
-            if len(F) > 1:
-                return False
-            if F[0][0] == 2:
-                return False
-            return True
-            
-        else:
+        F = arith.factor(n)
+        if len(F) > 1:
             return False
-
-        
+        if F[0][0] == 2:
+            return False
+        return True
+
     def multiplicative_generator(self):
         """
@@ -398,13 +393,4 @@
             return a
             
-    def quadratic_nonresidue(self):
-        try:
-            return self._nonresidue
-        except AttributeError:
-            for a in self:
-                if not a.is_square():
-                    self._nonresidue = a
-                    return a
-            
     def factored_order(self):
         """
@@ -462,5 +448,5 @@
     def order(self):
         return self.__order
-        
+
     def cardinality(self):
         return self.order()
Index: sage/rings/integer_ring.pxd
===================================================================
--- sage/rings/integer_ring.pxd	(revision 4057)
+++ sage/rings/integer_ring.pxd	(revision 3665)
@@ -8,3 +8,2 @@
     cdef Integer _coerce_ZZ(self, ntl_c_ZZ *z)
     cdef int _randomize_mpz(self, mpz_t value, x, y, distribution) except -1
-    cdef object _zero
Index: sage/rings/integer_ring.pyx
===================================================================
--- sage/rings/integer_ring.pyx	(revision 4010)
+++ sage/rings/integer_ring.pyx	(revision 3665)
@@ -28,10 +28,4 @@
     sage: Z('94803849083985934859834583945394')
     94803849083985934859834583945394
-
-TESTS:
-    sage: Z = IntegerRing()
-    sage: Z == loads(dumps(Z))
-    True
-
 """
 
Index: sage/rings/laurent_series_ring_element.py
===================================================================
--- sage/rings/laurent_series_ring_element.py	(revision 4059)
+++ sage/rings/laurent_series_ring_element.py	(revision 3574)
@@ -17,5 +17,5 @@
     IndexError: Laurent series are immutable    
 
-We compute with a Laurent series over the complex mpfr numbers. 
+We compute with a Laurent series over a the complex mpfr numbers. 
     sage: K.<q> = Frac(CC[['q']])
     sage: K
@@ -112,5 +112,5 @@
         return self.__u.is_unit()
 
-    def __nonzero__(self):
+    def is_zero(self):
         """
         EXAMPLES:
@@ -123,5 +123,5 @@
             1
         """
-        return not self.__u.is_zero()
+        return self.__u.is_zero()
         
     def _im_gens_(self, codomain, im_gens):
@@ -748,5 +748,5 @@
         return t**(self.__n) * u
         
-    def __call__(self, *x):
+    def __call__(self, x):
         """
         Compute value of this Laurent series at x.
@@ -762,7 +762,5 @@
             82/9
         """
-        if isinstance(x[0], tuple):
-            x = x[0]
-        return self.__u(x) * (x[0]**self.__n)
-
-
+        return self.__u(x) * (x**self.__n)
+
+
Index: sage/rings/morphism.py
===================================================================
--- sage/rings/morphism.py	(revision 4057)
+++ sage/rings/morphism.py	(revision 3354)
@@ -282,20 +282,4 @@
     sage: i(beta^2 + 1)
     2.58740105196820
-
-TESTS:
-    sage: H = Hom(ZZ, QQ)
-    sage: H == loads(dumps(H))
-    True
-
-    sage: K.<zeta7> = CyclotomicField(7)
-    sage: c = K.hom([1/zeta7])
-    sage: c == loads(dumps(c))
-    True
-
-    sage: R.<t> = PowerSeriesRing(GF(5))
-    sage: f = R.hom([t^5])
-    sage: f == loads(dumps(f))
-    True
-
 """
 
@@ -348,6 +332,4 @@
           To:   Polynomial Ring in x, y over Rational Field
           Defn: Choice of lifting map
-        sage: S.lift() == 0
-        False
     """
     def __init__(self, R, S):
@@ -360,9 +342,4 @@
             raise TypeError, "No natural lift map"
 
-    def __cmp__(self, other):
-        if not isinstance(other, RingMap_lift):
-            return cmp(type(self), type(other))
-        return 0
-        
     def _repr_defn(self):
         return "Choice of lifting map"
@@ -402,8 +379,5 @@
         A *ring* homomorphism is considered to be 0 if and only if
         it sends the 1 element of the domain to the 0 element of the
-        codomain.  Since rings in SAGE all have a 1 element, the
-        zero homomorphism is only to a ring of order 1, where 1==0,
-        e.g., the ring \code{Integers(1)}.
-        
+        codomain.
 
         EXAMPLES:
@@ -479,48 +453,4 @@
         return self.__im_gens
 
-    def __cmp__(self, other):
-        """
-        EXAMPLES:
-        A single variate quotient over QQ.
-            sage: R.<x> = QQ[]
-            sage: Q.<a> = R.quotient(x^2 + x + 1)
-            sage: f1 = R.hom([a])
-            sage: f2 = R.hom([a + a^2 + a + 1])
-            sage: f1 == f2
-            True
-            sage: f1 == R.hom([a^2])
-            False
-            sage: f1(x^3 + x)
-            a + 1
-            sage: f2(x^3 + x)
-            a + 1
-
-        TESTS:
-            sage: loads(dumps(f2)) == f2
-            True
-
-        EXAMPLES:
-        A multivariate quotient over a finite field.
-            sage: R.<x,y> = GF(7)[]
-            sage: Q.<a,b> = R.quotient([x^2 + x + 1, y^2 + y + 1])
-            sage: f1 = R.hom([a, b])
-            sage: f2 = R.hom([a + a^2 + a + 1, b + b^2 + b + 1])
-            sage: f1 == f2
-            True
-            sage: f1 == R.hom([b,a])
-            False
-            sage: f1(x^3 + x + y^2)
-            6*b + a
-            sage: f2(x^3 + x + y^2)
-            6*b + a
-
-        TEST:
-            sage: loads(dumps(f2)) == f2
-            True
-        """
-        if not isinstance(other, RingHomomorphism_im_gens):
-            return cmp(type(self), type(other))
-        return cmp(self.__im_gens, other.__im_gens)
-
     def _repr_defn(self):
         D = self.domain()
@@ -547,6 +477,6 @@
         b + a
     """
-    def __init__(self, parent):
-        RingHomomorphism.__init__(self, parent)
+    def __init__(self, ring, quotient_ring):
+        RingHomomorphism.__init__(self, ring.Hom(quotient_ring))
 
     def _call_(self, x):
@@ -559,18 +489,4 @@
         return self.codomain().defining_ideal()
     
-    def __cmp__(self, other):
-        """
-        EXAMPLES:
-            sage: R.<x,y> = PolynomialRing(QQ, 2)
-            sage: S.<a,b> = R.quo(x^2 + y^2)
-            sage: phi = S.cover()
-            sage: phi == loads(dumps(phi))
-            True
-            sage: phi == R.quo(x^2 + y^3).cover()
-            False
-        """
-        if not isinstance(other, RingHomomorphism_cover):
-            return cmp(type(self), type(other))
-        return 0  # since parents are the same, i.e., both cover maps with same domain and codomain
 
 class RingHomomorphism_from_quotient(RingHomomorphism):
@@ -601,6 +517,5 @@
         sage: phi(a+b+c)
         c + b + a
-        sage: loads(dumps(phi)) == phi
-        True        
+        
 
      Validity of the homomorphism is determined, when possible, and a
@@ -624,30 +539,6 @@
         self.__phi = phi
 
-    def _phi(self):
-        """
-        Underlying morphism used to define this quotient map (i.e.,
-        morphism from the cover of the domain).
-        """
-        return self.__phi
-
     def morphism_from_cover(self):
         return self.__phi
-
-    def __cmp__(self, other):
-        """
-        EXAMPLES:
-            sage: R.<x, y, z> = PolynomialRing(GF(19), 3)
-            sage: S.<a, b, c> = R.quo(x^3 + y^3 + z^3)
-            sage: phi = S.hom([b, c, a])
-            sage: psi = S.hom([c, b, a])
-            sage: f = S.hom([b, c, a + a^3 + b^3 + c^3])
-            sage: phi == psi
-            False
-            sage: phi == f
-            True
-        """
-        if not isinstance(other, RingHomomorphism_from_quotient):
-            return cmp(type(self), type(other))
-        return cmp(self.__phi, other.__phi)
 
     def _repr_defn(self):
Index: sage/rings/mpfr.pxi
===================================================================
--- sage/rings/mpfr.pxi	(revision 3927)
+++ sage/rings/mpfr.pxi	(revision 3366)
@@ -12,5 +12,4 @@
     ctypedef struct __mpfr_struct:
         pass
-        
     #ctypedef __mpfr_struct mpfr_t[1]
     ctypedef __mpfr_struct* mpfr_t
@@ -51,8 +50,5 @@
     void mpfr_free_str (char *str)
 
-    void mpfr_get_z(mpz_t rop, mpfr_t op, mp_rnd_t rnd)
     mp_exp_t mpfr_get_z_exp(mpz_t rop, mpfr_t op)
-
-    void mpfr_urandomb(mpfr_t rop, void* rnd_state)
 
     # Arithmetic
@@ -149,3 +145,2 @@
     int mpfr_lessequal_p (mpfr_t op1, mpfr_t op2)
     int mpfr_cmp (mpfr_t op1, mpfr_t op2)
-    int mpfr_equal_p (mpfr_t op1, mpfr_t op2)
Index: sage/rings/multi_polynomial_element.py
===================================================================
--- sage/rings/multi_polynomial_element.py	(revision 4061)
+++ sage/rings/multi_polynomial_element.py	(revision 3134)
@@ -69,66 +69,4 @@
         return "%s"%self.__element
 
-    ####################
-    # Some standard conversions
-    ####################
-    def __int__(self):
-        if self.degree() == 0:
-            return int(self.constant_coefficient())
-        else:
-            raise TypeError
-        
-    def __long__(self):
-        if self.degree() == 0:
-            return long(self.constant_coefficient())
-        else:
-            raise TypeError
-
-    def __float__(self):
-        if self.degree() == 0:
-            return float(self.constant_coefficient())
-        else:
-            raise TypeError
-
-    def _mpfr_(self, R):
-        if self.degree() == 0:
-            return R(self.constant_coefficient())
-        else:
-            raise TypeError
-
-    def _complex_mpfr_field_(self, R):
-        if self.degree() == 0:
-            return R(self.constant_coefficient())
-        else:
-            raise TypeError
-
-    def _complex_double_(self, R):
-        if self.degree() == 0:
-            return R(self.constant_coefficient())
-        else:
-            raise TypeError
-
-    def _real_double_(self, R):
-        if self.degree() == 0:
-            return R(self.constant_coefficient())
-        else:
-            raise TypeError
-        
-    def _rational_(self):
-        if self.degree() == 0:
-            from rational import Rational
-            return Rational(repr(self))
-        else:
-            raise TypeError
-
-    def _integer_(self):
-        if self.degree() == 0:
-            from integer import Integer
-            return Integer(repr(self))
-        else:
-            raise TypeError
-    
-
-    ####################
-
     def __call__(self, *x):
         """
@@ -287,5 +225,5 @@
     def __pow__(self, n):
         if not isinstance(n, (int, long, integer.Integer)):
-            n = integer.Integer(n)
+            raise TypeError, "The exponent must be an integer."
         if n < 0:
             return 1/(self**(-n))
@@ -367,5 +305,5 @@
 
         INPUT:
-            x -- multivariate polynomial (a generator of the parent of self)
+            x -- multivariate polynmial (a generator of the parent of self)
                  If x is not specified (or is None), return the total degree,
                  which is the maximum degree of any monomial.
@@ -549,6 +487,6 @@
             sage: c = f.coefficient(x*y); c
             2
-            sage: c.parent()
-            Polynomial Ring in x, y over Rational Field
+            sage: c in QQ
+            False
             sage: c in MPolynomialRing(RationalField(), 2, names = ['x','y'])
             True
@@ -1033,11 +971,11 @@
         return self._MPolynomial__element != right._MPolynomial__element
 
-    def __nonzero__(self):
-        """
-        Returns True if self != 0
+    def is_zero(self):
+        """
+        Returns True if self == 0
 
         \note{This is much faster than actually writing self == 0}
         """
-        return self._MPolynomial__element.dict()!={}
+        return self._MPolynomial__element.dict()=={}
 
     ############################################################################
Index: sage/rings/multi_polynomial_ideal.py
===================================================================
--- sage/rings/multi_polynomial_ideal.py	(revision 4057)
+++ sage/rings/multi_polynomial_ideal.py	(revision 3645)
@@ -61,11 +61,4 @@
     sage: 0 in j                                                # optional
     True
-
-TESTS:
-    sage: x,y,z = QQ['x,y,z'].gens()
-    sage: I = ideal(x^5 + y^4 + z^3 - 1,  x^3 + y^3 + z^2 - 1)
-    sage: I == loads(dumps(I))
-    True
-
 """
 
@@ -337,8 +330,8 @@
         return self.__dimension
         
-    def _groebner_basis_using_singular(self, algorithm="groebner"):
+    def _singular_groebner_basis(self, algorithm="groebner"):
         """
         Return a Groebner basis of this ideal. If a groebner basis for
-        this ideal has been calculated before the cached Groebner
+        this ideal has been calculated before the cached groebner
         basis is returned regardless of the requested algorithm.
 
@@ -364,6 +357,12 @@
             sage: I = sage.rings.ideal.Cyclic(R,4); I
             Ideal (d + c + b + a, c*d + b*c + a*d + a*b, b*c*d + a*c*d + a*b*d + a*b*c, -1 + a*b*c*d) of Polynomial Ring in a, b, c, d over Rational Field
-            sage: I._groebner_basis_using_singular()
+            sage: I.groebner_basis()
             [1 - d^4 - c^2*d^2 + c^2*d^6, -1*d - c + c^2*d^3 + c^3*d^2, -1*d + d^5 - b + b*d^4, -1*d^2 - d^6 + c*d + c^2*d^4 - b*d^5 + b*c, d^2 + 2*b*d + b^2, d + c + b + a]
+            
+        \note{Some Groebner basis calculations crash on 64-bit
+        opterons with \SAGE's singular build, but work fine with an
+        official binary.  If you download and install a Singular
+        binary from the Singular website it will not have this problem
+        (you can use it with \SAGE by putting it in local/bin/).}
         """
         try:
@@ -388,25 +387,4 @@
         return self.__groebner_basis
 
-    def _singular_groebner_basis(self):
-        try:
-            S = self.__singular_groebner_basis
-        except AttributeError:
-            G = self.groebner_basis()
-            try:
-                return self.__singular_groebner_basis
-            except AttributeError:
-                pass
-
-        try:
-            S._check_valid()
-            return S
-        except ValueError:
-            G = self.groebner_basis()
-            S = singular(G)
-            self.__singular_groebner_basis = S
-        return S
-            
-    
-
     def genus(self):
         """
@@ -569,14 +547,15 @@
         if self.base_ring() == sage.rings.integer_ring.ZZ:
             return self._reduce_using_macaulay2(f)
-
-        try:
-            singular = self._singular_groebner_basis().parent()
-        except (AttributeError, RuntimeError):
-            singular = self._singular_groebner_basis().parent()
+        
+        try:
+            singular = self.__singular_groebner_basis.parent()
+        except AttributeError:
+            self.groebner_basis()
+            singular = self.__singular_groebner_basis.parent()
         
         f = self.ring()(f)
         g = singular(f)
         try:
-            h = g.reduce(self._singular_groebner_basis())
+            h = g.reduce(self.__singular_groebner_basis)
         except TypeError:
             # This is OK, since f is in the right ring -- type error
@@ -877,7 +856,7 @@
                 return self._macaulay2_groebner_basis()
             else:
-                return self._groebner_basis_using_singular("groebner")
+                return self._singular_groebner_basis("groebner")
         elif algorithm.startswith('singular:'):
-            return self._groebner_basis_using_singular(algorithm[9:])
+            return self._singular_groebner_basis(algorithm[9:])
         elif algorithm == 'macaulay2:gb':
             return self._macaulay2_groebner_basis()
Index: sage/rings/multi_polynomial_ring.py
===================================================================
--- sage/rings/multi_polynomial_ring.py	(revision 4065)
+++ sage/rings/multi_polynomial_ring.py	(revision 2665)
@@ -83,5 +83,4 @@
 
 from sage.structure.parent_gens import ParentWithGens
-
 
 
@@ -251,7 +250,4 @@
 
 
-    def is_exact(self):
-        return self.base_ring().is_exact()
-
     def is_finite(self):
         if self.ngens() == 0:
@@ -419,30 +415,5 @@
             sage: f = x^2 + 2/3*y^3
             sage: S(f)
-            3*b^3 + a^2
-
-        Coercion from symbolic variables:
-            sage: x,y,z = var('x,y,z')
-            sage: R = QQ[x,y,z]
-            sage: type(x)
-            <class 'sage.calculus.calculus.SymbolicVariable'>
-            sage: type(R(x))
-            <class 'sage.rings.multi_polynomial_element.MPolynomial_polydict'>
-            sage: f = R(x^3 + y^3 - z^3); f
-            -1*z^3 + y^3 + x^3
-            sage: type(f)
-            <class 'sage.rings.multi_polynomial_element.MPolynomial_polydict'>
-            sage: parent(f)
-            Polynomial Ring in x, y, z over Rational Field
-
-        A more complicated symbolic and computational mix.  Behind the scenes
-        Singular and Maxima are doing the real work. 
-            sage: R = QQ[x,y,z]
-            sage: f = (x^3 + y^3 - z^3)^10; f
-            (-z^3 + y^3 + x^3)^10
-            sage: g = R(f); parent(g)
-            Polynomial Ring in x, y, z over Rational Field
-            sage: (f - g).expand()
-            0
-            
+            3*b^3 + a^2        
         """
         if isinstance(x, multi_polynomial_element.MPolynomial_polydict):
@@ -467,5 +438,4 @@
         elif isinstance(x, polydict.PolyDict):
             return multi_polynomial_element.MPolynomial_polydict(self, x)
-        
         elif isinstance(x, fraction_field_element.FractionFieldElement) and x.parent().ring() == self:
             if x.denominator() == 1:
@@ -473,5 +443,4 @@
             else:
                 raise TypeError, "unable to coerce since the denominator is not 1"
-
         elif is_SingularElement(x) and self._has_singular:
             self._singular_().set_ring()
@@ -480,8 +449,4 @@
             except:
                 raise TypeError, "Unable to coerce singular object"
-
-        elif hasattr(x, '_polynomial_'):
-            return x._polynomial_(self)
-        
         elif isinstance(x , str) and self._has_singular:
             self._singular_().set_ring()
@@ -490,5 +455,4 @@
             except:
                 raise TypeError,"Unable to coerce string"
-            
         elif is_Macaulay2Element(x):
             try:
@@ -504,10 +468,6 @@
                 raise TypeError, "Unable to coerce macaulay2 object"
             return multi_polynomial_element.MPolynomial_polydict(self, x)
-
-        if isinstance(x, dict):
-            return multi_polynomial_element.MPolynomial_polydict(self, x)
-        else:
-            c = self.base_ring()(x)
-            return multi_polynomial_element.MPolynomial_polydict(self, {self._zero_tuple:c})
+        c = self.base_ring()(x)
+        return multi_polynomial_element.MPolynomial_polydict(self, {self._zero_tuple:c})
 
 
Index: sage/rings/number_field/number_field.py
===================================================================
--- sage/rings/number_field/number_field.py	(revision 4058)
+++ sage/rings/number_field/number_field.py	(revision 3650)
@@ -98,7 +98,8 @@
 
     EXAMPLES: Constructing a relative number field
+        sage: R.<x> = PolynomialRing(QQ)
         sage: K.<a> = NumberField(x^2 - 2)
-        sage: R.<t> = K[]
-        sage: L = K.extension(t^3+t+a, b); L
+        sage: R.<t> = K['t']
+        sage: L = K.extension(t^3+t+a, 'b'); L
         Extension by t^3 + t + a of the Number Field in a with defining polynomial x^2 - 2
         sage: L.absolute_field()
@@ -124,11 +125,4 @@
 
     name = sage.structure.parent_gens.normalize_names(1, name)
-    if not isinstance(polynomial, polynomial_element.Polynomial):
-        try:
-            polynomial = polynomial.polynomial(QQ)
-        except (AttributeError, TypeError):
-            raise TypeError, "polynomial (=%s) must be a polynomial."%repr(polynomial)
-
-    
     key = (polynomial, name)
     if _nf_cache.has_key(key):
@@ -185,4 +179,5 @@
     """
     EXAMPLES:
+        sage: R.<x> = PolynomialRing(QQ)    
         sage: K.<a> = NumberField(x^3 - 2); K
         Number Field in a with defining polynomial x^3 - 2
@@ -194,5 +189,5 @@
         ParentWithGens.__init__(self, QQ, name)
         if not isinstance(polynomial, polynomial_element.Polynomial):
-            raise TypeError, "polynomial (=%s) must be a polynomial"%repr(polynomial)
+            raise TypeError, "polynomial (=%s) must be a polynomial"%polynomial
         
         if check:
@@ -214,14 +209,5 @@
 
     def __reduce__(self):
-        """
-        TESTS:
-            sage: K.<w> = NumberField(Z^3 + Z + 1)
-            sage: L = loads(dumps(K))
-            sage: print L
-            Number Field in w with defining polynomial Z^3 + Z + 1
-            sage: print L == K
-            True
-        """
-        return NumberField_generic_v1, (self.__polynomial, self.variable_name(), self.__latex_variable_name)
+        return NumberField_generic, (self.__polynomial, self.variable_name(), self.__latex_variable_name)
 
     def complex_embeddings(self, prec=53):
@@ -231,5 +217,4 @@
 
         EXAMPLES:
-            sage: x = polygen(QQ)
             sage: f = x^5 + x + 17
             sage: k.<a> = NumberField(f)
@@ -257,5 +242,5 @@
             self.__latex_variable_name = name
 
-    def _repr_(self):
+    def __repr__(self):
         return "Number Field in %s with defining polynomial %s"%(
                    self.variable_name(), self.polynomial())
@@ -290,8 +275,4 @@
                               list)):
             return number_field_element.NumberFieldElement(self, x)
-        try:
-            return number_field_element.NumberFieldElement(self, x._rational_())
-        except (TypeError, AttributeError):
-            pass
         raise TypeError, "Cannot coerce %s into %s"%(x,self)
 
@@ -299,7 +280,10 @@
         if isinstance(x, (rational.Rational, integer.Integer, int, long)):
             return number_field_element.NumberFieldElement(self, x)
-        elif isinstance(x, number_field_element.NumberFieldElement) and x.parent() == self:
-            return number_field_element.NumberFieldElement(self, x.list())
         raise TypeError
+
+    def category(self):
+        from sage.categories.all import NumberFields
+        return NumberFields()
+    
 
     def category(self):
@@ -325,4 +309,5 @@
 
         EXAMPLES:
+            sage: R.<x> = PolynomialRing(QQ)
             sage: K.<a> = NumberField(x^3-2)
             sage: K.ideal([a])
@@ -466,4 +451,5 @@
 
         EXAMPLES:
+            sage: R.<x> = PolynomialRing(QQ)
             sage: K.<a> = NumberField(x^2+1)
             sage: K.elements_of_norm(3)
@@ -482,30 +468,14 @@
 
         EXAMPLES:
+            sage: R.<x> = PolynomialRing(QQ)
             sage: K.<a> = NumberField(x^3 - 2)
-            sage: R.<t> = K[]
+            sage: t = K['x'].gen()
             sage: L.<b> = K.extension(t^2 + a); L
-            Extension by t^2 + a of the Number Field in a with defining polynomial x^3 - 2
-
-        We create another extension.
-            sage: k.<a> = NumberField(x^2 + 1); k
-            Number Field in a with defining polynomial x^2 + 1
-            sage: m.<b> = k.extension(y^2 + 1); m
-            Extension by y^2 + 1 of the Number Field in a with defining polynomial x^2 + 1
-            sage: b.minpoly()
-            x^4 + 10*x^2 + 9
-            
-        """
-        if not isinstance(poly, polynomial_element.Polynomial):
-            try:
-                poly = poly.polynomial(self)
-            except (AttributeError, TypeError):
-                raise TypeError, "polynomial (=%s) must be a polynomial."%repr(poly)
-        if not names is None:
-            name = names
-        if isinstance(name, tuple):
-            name = name[0]
+            Extension by x^2 + a of the Number Field in a with defining polynomial x^3 - 2
+        """
+        if not names is None: name = names
         if name is None:
             raise TypeError, "the variable name must be specified."
-        return NumberField_extension(self, poly, repr(name))
+        return NumberField_extension(self, poly, name)
 
     def factor_integer(self, n):
@@ -518,4 +488,5 @@
         First we form a number field defined by $x^2 + 1$:
  
+            sage: R.<x> = PolynomialRing(QQ)
             sage: K.<I> = NumberField(x^2 + 1); K
             Number Field in I with defining polynomial x^2 + 1
@@ -572,4 +543,6 @@
 
         EXAMPLES:
+            sage: R.<x> = PolynomialRing(QQ)
+
             sage: NumberField(x^3-2, 'a').galois_group(pari_group=True)
             PARI group [6, -1, 2, "S3"] of degree 3
@@ -591,5 +564,6 @@
 
         EXAMPLES:
-            sage: K.<a> = NumberField(x^5 + 10*x + 1)
+            sage: x = polygen(QQ,'x')
+            sage: K.<a> = NumberField(x^5+10*x+1)
             sage: K.integral_basis()
             [1, a, a^2, a^3, a^4]
@@ -616,4 +590,5 @@
         
         EXAMPLES:
+            sage: R.<x> = PolynomialRing(QQ)
             sage: NumberField(x^3+x+9, 'a').narrow_class_group()
             Multiplicative Abelian Group isomorphic to C2
@@ -662,4 +637,5 @@
 
         EXAMPLES:
+            sage: R.<x> = PolynomialRing(QQ)
             sage: K = NumberField(x^3 + 2*x - 5, 'alpha')
             sage: K.polynomial_quotient_ring()
@@ -676,4 +652,5 @@
 
         EXAMPLES:
+            sage: R.<x> = PolynomialRing(QQ)
             sage: NumberField(x^2-2, 'a').regulator()
             0.88137358701954305
@@ -695,4 +672,5 @@
 
         EXAMPLES:
+            sage: R.<x> = PolynomialRing(QQ)
             sage: NumberField(x^2+1, 'a').signature()
             (0, 1)
@@ -711,4 +689,5 @@
 
         EXAMPLES:
+            sage: R.<x> = PolynomialRing(QQ)
             sage: K.<zeta3> = NumberField(x^2 + 3)
             sage: K.trace_pairing([1,zeta3])
@@ -836,4 +815,5 @@
     """
     EXAMPLES:
+        sage: R.<x> = PolynomialRing(QQ)
         sage: K.<a> = NumberField(x^3 - 2)
         sage: t = K['x'].gen()
@@ -850,8 +830,5 @@
             raise TypeError, "base (=%s) must be a number field"%base
         if not isinstance(polynomial, polynomial_element.Polynomial):
-            try:
-                polynomial = polynomial.polynomial(base)
-            except (AttributeError, TypeError), msg:
-                raise TypeError, "polynomial (=%s) must be a polynomial."%repr(polynomial)
+            raise TypeError, "polynomial (=%s) must be a polynomial"%polynomial
         if name == base.variable_name():
             raise ValueError, "Base field and extension cannot have the same name"
@@ -897,19 +874,5 @@
         self.__pari_bnf_certified = False
 
-    def __reduce__(self):
-        """
-        TESTS:
-            sage: K.<w> = NumberField(Z^3 + Z + 1)
-            sage: L.<z> = K.extension(Z^3 + 2)
-            sage: L = loads(dumps(K))
-            sage: print L
-            Number Field in w with defining polynomial Z^3 + Z + 1
-            sage: print L == K
-            True        
-        """
-        return NumberField_extension_v1, (self.__base_field, self.polynomial(), self.variable_name(),
-                                          self.latex_variable_name())
-
-    def _repr_(self):
+    def __repr__(self):
         return "Extension by %s of the Number Field in %s with defining polynomial %s"%(
             self.polynomial(), self.base_field().variable_name(),
@@ -1060,5 +1023,5 @@
             pbn = self._pari_base_nf()
             prp = self.pari_relative_polynomial()
-            pari_poly = pbn.rnfequation(prp)
+            pari_poly = str(pbn.rnfequation(prp)).replace('^', '**')
             R = self.base_field().polynomial().parent()
             self.__absolute_polynomial = R(pari_poly)
@@ -1222,17 +1185,5 @@
         self.__zeta_order = n
 
-    def __reduce__(self):
-        """
-        TESTS:
-            sage: K.<zeta7> = CyclotomicField(7)
-            sage: L = loads(dumps(K))
-            sage: print L
-            Cyclotomic Field of order 7 and degree 6
-            sage: print L == K
-            True
-        """
-        return NumberField_cyclotomic_v1, (self.__zeta_order, self.variable_name())
-
-    def _repr_(self):
+    def __repr__(self):
         return "Cyclotomic Field of order %s and degree %s"%(
                 self.zeta_order(), self.degree())
@@ -1540,15 +1491,4 @@
         NumberField_generic.__init__(self, polynomial, name=name, check=check)
         
-    def __reduce__(self):
-        """
-        TESTS:
-            sage: K.<z7> = QuadraticField(7)
-            sage: L = loads(dumps(K))
-            sage: print L
-            Number Field in z7 with defining polynomial x^2 - 7
-            sage: print L == K
-            True
-        """
-        return NumberField_quadratic_v1, (self.polynomial(), self.variable_name())
 
     def class_number(self, proof = True):
@@ -1625,19 +1565,2 @@
            (arith.is_squarefree(D) or \
             (d == 0 and (D//4)%4 in [2,3] and arith.is_squarefree(D//4)))
-
-
-###################
-# For pickling
-###################
-
-def NumberField_generic_v1(poly, name, latex_name):
-    return NumberField_generic(poly, name, latex_name, check=False)
-
-def NumberField_extension_v1(base_field, poly, name, latex_name):
-    return NumberField_extension(base_field, poly, name, latex_name, check=False)
-
-def NumberField_cyclotomic_v1(zeta_order, name):
-    return NumberField_cyclotomic(zeta_order, name)
-
-def NumberField_quadratic_v1(poly, name):
-    return NumberField_quadratic(poly, name, check=False)
Index: sage/rings/number_field/number_field_ideal.py
===================================================================
--- sage/rings/number_field/number_field_ideal.py	(revision 4019)
+++ sage/rings/number_field/number_field_ideal.py	(revision 2725)
@@ -4,12 +4,4 @@
 AUTHOR:
    -- Steven Sivek (2005-05-16)
-
-TESTS:
-    sage: K.<a> = NumberField(x^2 - 5)
-    sage: I = K.ideal(2/(5+a))
-    sage: I == loads(dumps(I))
-    True
-
-
 """
 
@@ -71,5 +63,7 @@
 
     def __cmp__(self, other):
-        return cmp(self.pari_hnf(), other.pari_hnf())
+        if self.pari_hnf() == other.pari_hnf():
+            return 0
+        return -1
 
     def _coerce_impl(self, x):
Index: sage/rings/padics/extension_local_field.py
===================================================================
--- sage/rings/padics/extension_local_field.py	(revision 3890)
+++ sage/rings/padics/extension_local_field.py	(revision 3667)
@@ -17,4 +17,5 @@
     def has_pth_root(self): pass
     def has_root_of_unity(self, n): pass
+    def hom(self, extension): pass
     def inertia_degree(self): pass
     def inertia_subfield(self): pass
Index: sage/rings/padics/extension_local_ring.py
===================================================================
--- sage/rings/padics/extension_local_ring.py	(revision 3890)
+++ sage/rings/padics/extension_local_ring.py	(revision 3667)
@@ -16,4 +16,5 @@
     def has_pth_root(self): pass
     def has_root_of_unity(self, n): pass
+    def hom(self, extension): pass
     def inertia_degree(self): pass
     def inertia_subring(self): pass
Index: sage/rings/padics/padic_extension_generic.py
===================================================================
--- sage/rings/padics/padic_extension_generic.py	(revision 3890)
+++ sage/rings/padics/padic_extension_generic.py	(revision 3678)
@@ -108,4 +108,7 @@
     #    raise NotImplementedError
 
+    #def hom(self, ring):
+    #    raise NotImplementedError
+
     def random_element(self):
         return reduce(lambda x,y: x+y,map(lambda a,b:a*b,[self.ground_ring().random_element() for _ in range(self.modulus().degree())],[self.gen()**i for i in range(self.modulus().degree())]),0)
Index: sage/rings/padics/padic_generic_element.py
===================================================================
--- sage/rings/padics/padic_generic_element.py	(revision 3804)
+++ sage/rings/padics/padic_generic_element.py	(revision 3680)
@@ -570,7 +570,8 @@
 
         AUTHORS:
+            -- William Stein: initial version
             -- David Harvey (2006-09-13): corrected subtle precision bug
                (need to take denominators into account! -- see trac \#53)
-            -- Genya Zaytman (2007-02-14): addapted to new p-adic class
+            -- Genya Zaytman (2007-02-14): adapted to new p-adic class
 
         TODO:
Index: sage/rings/polydict.pyx
===================================================================
--- sage/rings/polydict.pyx	(revision 4006)
+++ sage/rings/polydict.pyx	(revision 2725)
@@ -570,11 +570,4 @@
 
     def __reduce__(PolyDict self):
-        """
-        sage: from sage.rings.polydict import PolyDict        
-        sage: f = PolyDict({(2,3):2, (1,2):3, (2,1):4})
-        sage: loads(dumps(f)) == f
-        True
-        
-        """
         return make_PolyDict,(self.__repn,)
     
@@ -839,12 +832,4 @@
 
     def __reduce__(ETuple self):
-        """
-        EXAMPLES:
-            sage: from sage.rings.polydict import ETuple
-            sage: e = ETuple([1,1,0])
-            sage: bool(e == loads(dumps(e)))
-            True
-        """
-
         return make_ETuple,(self._data,self._length)
 
Index: sage/rings/polynomial_element.pxd
===================================================================
--- sage/rings/polynomial_element.pxd	(revision 4061)
+++ sage/rings/polynomial_element.pxd	(revision 3650)
@@ -5,8 +5,7 @@
 
 from sage.structure.element import Element, CommutativeAlgebraElement
-from sage.structure.element cimport Element, CommutativeAlgebraElement, ModuleElement
+from sage.structure.element cimport Element, CommutativeAlgebraElement
 
 cdef class Polynomial(CommutativeAlgebraElement):
-    cdef ModuleElement _neg_c_impl(self)
     cdef char _is_gen
 
Index: sage/rings/polynomial_element.pyx
===================================================================
--- sage/rings/polynomial_element.pyx	(revision 4061)
+++ sage/rings/polynomial_element.pyx	(revision 3605)
@@ -5,11 +5,4 @@
     -- William Stein: first version
     -- Martin Albrecht: Added singular coercion.
-
-TESTS:
-     sage: R.<x> = ZZ[]
-     sage: f = x^5 + 2*x^2 + (-1)
-     sage: f == loads(dumps(f))
-     True
-
 """
 
@@ -102,7 +95,4 @@
         self._is_gen = is_gen
 
-    cdef ModuleElement _neg_c_impl(self):
-        return self.polynomial([-x for x in self.list()])
-
     def _add_(self, right):
         if self.degree() >= right.degree():
@@ -152,5 +142,5 @@
         return self * self.parent()(right) 
         
-    def __call__(self, *x):
+    def __call__(self, *a):
         """
         Evaluate polynomial at x=a using Horner's rule
@@ -202,21 +192,5 @@
             Full MatrixSpace of 2 by 2 dense matrices over Rational Field
             
-        Nested polynomial ring elements can be called like multi-variate polynomials.
-            sage: R.<x> = QQ[]
-            sage: S.<y> = R[]
-            sage: f = x+y*x+y^2
-            sage: f.parent()
-            Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
-            sage: f(2)
-            3*x + 4
-            sage: f(2,4)
-            16
-            sage: R.<t> = PowerSeriesRing(QQ, 't'); S.<x> = R[]
-            sage: f = 1 + x*t^2 + 3*x*t^4
-            sage: f(2)
-            1 + 2*t^2 + 6*t^4
-            sage: f(2, 1/2)
-            15/8
-            
+
         AUTHORS:
             -- David Joyner, 2005-04-10
@@ -224,19 +198,10 @@
                is determined by the arithmetic
             -- William Stein, 2007-03-24: fix parent being determined in the constant case!
-            -- Robert Bradshaw, 2007-04-09: add support for nested calling
-        """
-        if isinstance(x[0], tuple):
-            x = x[0]
-        a = x[0]
-
+        """
+        a = a[0]
+        if isinstance(a, tuple):
+            a = a[0]
         d = self.degree()
         result = self[d]
-        if len(x) > 1:
-            other_args = x[1:]
-            if hasattr(result, '__call__'):
-                result = result(other_args)
-            else:
-                raise TypeError, "Wrong number of arguments"
-                
         if d == 0:
             try:
@@ -244,14 +209,8 @@
             except AttributeError:
                 return result
-
         i = d - 1
-        if len(x) > 1:
-            while i >= 0:
-                result = result * a + self[i](other_args)
-                i -= 1
-        else:
-            while i >= 0:
-                result = result * a + self[i]
-                i -= 1
+        while i >= 0:
+            result = result * a + self[i]
+            i -= 1
         return result
 
@@ -507,5 +466,5 @@
                 if n != m-1:
                     s += " + "
-                x = repr(x)
+                x = str(x)
                 if not atomic_repr and n > 0 and (x.find("+") != -1 or x.find("-") != -1):
                     x = "(%s)"%x
@@ -528,5 +487,4 @@
         r"""
         EXAMPLES:
-			sage: x = polygen(QQ)
             sage: f = x^3+2/3*x^2 - 5/3
             sage: f._repr_()
@@ -541,5 +499,4 @@
         r"""
         EXAMPLES:
-			sage: x = polygen(QQ)
             sage: latex(x^3+2/3*x^2 - 5/3)
              x^{3} + \frac{2}{3}x^{2} - \frac{5}{3}
@@ -951,5 +908,5 @@
             
         Notice that the unit factor is included when we multiply $F$ back out.
-            sage: expand(F)
+            sage: F.mul()
             2*x^10 + 2*x + 2*a
 
@@ -986,5 +943,5 @@
             sage: F = factor(x^2-3); F
             (1.0000000000000000000000000000*x + 1.7320508075688772935274463415) * (1.0000000000000000000000000000*x - 1.7320508075688772935274463415)
-            sage: expand(F)
+            sage: F.mul()
             1.0000000000000000000000000000*x^2 - 3.0000000000000000000000000000
             sage: factor(x^2 + 1)
@@ -994,5 +951,5 @@
             sage: F = factor(x^2+3); F
             (1.0000000000000000000000000000*x + -1.7320508075688772935274463415*I) * (1.0000000000000000000000000000*x + 1.7320508075688772935274463415*I)
-            sage: expand(F)
+            sage: F.mul()
             1.0000000000000000000000000000*x^2 + 3.0000000000000000000000000000
             sage: factor(x^2+1)
@@ -1000,7 +957,7 @@
             sage: f = C.0 * (x^2 + 1) ; f
             1.0000000000000000000000000000*I*x^2 + 1.0000000000000000000000000000*I
-            sage: F = factor(f); F
+            sage: F=factor(f); F
             (1.0000000000000000000000000000*I) * (1.0000000000000000000000000000*x + -1.0000000000000000000000000000*I) * (1.0000000000000000000000000000*x + 1.0000000000000000000000000000*I)
-            sage: expand(F)
+            sage: F.mul()
             1.0000000000000000000000000000*I*x^2 + 1.0000000000000000000000000000*I
         """
@@ -1256,4 +1213,7 @@
         return bool(self._is_gen)
 
+    def is_zero(self):
+        return bool(self.degree() == -1)
+
     def leading_coefficient(self):
         return self[self.degree()]
@@ -1420,5 +1380,5 @@
 
     def _pari_init_(self):
-        return repr(self._pari_())
+        return str(self._pari_())
 
     def _magma_init_(self):
@@ -1465,5 +1425,5 @@
 
     def _gap_init_(self):
-        return repr(self)
+        return str(self)
 
     def _gap_(self, G):
@@ -1574,14 +1534,7 @@
 
             sage: x = CC['x'].0
-            sage: i = CC.0
-            sage: f = (x - 1)*(x - i)
+            sage: f = (x-1)*(x-I)
             sage: f.roots()
             [1.00000000000000*I, 1.00000000000000]
-
-        A purely symbolic roots example:
-            sage: f = expand((X-1)*(X-I)^3*(X^2 - sqrt(2))); f
-            X^6 - 3*I*X^5 - X^5 + 3*I*X^4 - sqrt(2)*X^4 - 3*X^4 + 3*sqrt(2)*I*X^3 + I*X^3 + sqrt(2)*X^3 + 3*X^3 - 3*sqrt(2)*I*X^2 - I*X^2 + 3*sqrt(2)*X^2 - sqrt(2)*I*X - 3*sqrt(2)*X + sqrt(2)*I
-            sage: print f.roots()
-            [(I, 3), (-2^(1/4), 1), (2^(1/4), 1), (1, 1)]
         """
         seq = []
Index: sage/rings/polynomial_element_generic.py
===================================================================
--- sage/rings/polynomial_element_generic.py	(revision 4061)
+++ sage/rings/polynomial_element_generic.py	(revision 3681)
@@ -70,8 +70,8 @@
 
         if fraction_field_element.is_FractionFieldElement(x):
-            if x.denominator().degree() >= 1:
-                raise TypeError, "denominator must be constant"
+            if x.denominator() != 1:
+                raise TypeError, "denominator must be 1"
             else:
-                x = x.numerator() * (~x.denominator()[0])
+                x = x.numerator()
                 
         if isinstance(x, Polynomial):
@@ -380,5 +380,5 @@
         EXAMPLES:
             sage: R.<w> = PolynomialRing(CDF, sparse=True)
-            sage: f = CDF(1,2) + w^5 - CDF(pi)*w + CDF(e)
+            sage: f = CDF(1,2) + w^5 - pi*w + e
             sage: f._repr()
             '1.0*w^5 + (-3.14159265359)*w + 3.71828182846 + 2.0*I'
@@ -400,5 +400,5 @@
                 if n != m-1:
                     s += " + "
-                x = repr(x)
+                x = str(x)
                 if not atomic_repr and n > 0 and (x.find("+") != -1 or x.find("-") != -1):
                     x = "(%s)"%x
@@ -434,5 +434,4 @@
         EXAMPLES:
             sage: R.<w> = PolynomialRing(RDF, sparse=True)
-            sage: e = RDF(e)
             sage: f = sum(e^n*w^n for n in range(4)); f
             20.0855369232*w^3 + 7.38905609893*w^2 + 2.71828182846*w + 1.0
@@ -1615,5 +1614,5 @@
                 if n != m:
                     s += " + "
-                x = repr(x)
+                x = str(x)
                 if not atomic_repr and n > 0 and (x.find("+") != -1 or x.find("-") != -1):
                     x = "(%s)"%x
Index: sage/rings/polynomial_pyx.pyx
===================================================================
--- sage/rings/polynomial_pyx.pyx	(revision 4059)
+++ sage/rings/polynomial_pyx.pyx	(revision 2725)
@@ -1144,6 +1144,6 @@
         return self.pq.degree 
 
-    def __nonzero__(self):
-        return self.pq.degree != -1
+    def is_zero(self):
+        return self.pq.degree == -1
 
     def list(self):
Index: sage/rings/polynomial_quotient_ring.py
===================================================================
--- sage/rings/polynomial_quotient_ring.py	(revision 4003)
+++ sage/rings/polynomial_quotient_ring.py	(revision 3480)
@@ -667,5 +667,4 @@
 
         EXAMPLES:
-            sage: x = polygen(QQ)
             sage: f = x^5 + x + 17
             sage: k = QQ['x'].quotient(f)
Index: sage/rings/polynomial_ring.py
===================================================================
--- sage/rings/polynomial_ring.py	(revision 4059)
+++ sage/rings/polynomial_ring.py	(revision 3679)
@@ -168,6 +168,6 @@
             except:
                 raise TypeError,"Unable to coerce string"
-        elif hasattr(x, '_polynomial_'):
-            return x._polynomial_(self)
+        # elif isinstance(x, multi_polynomial_element.MPolynomial_polydict):
+        #    return x.univariate_polynomial(self)
         elif is_MagmaElement(x):
             x = list(x.Eltseq())
@@ -435,7 +435,4 @@
             return True
         return False
-
-    def is_exact(self):
-        return self.base_ring().is_exact()
 
     def is_field(self):
@@ -831,6 +828,4 @@
             except:
                 raise TypeError,"Unable to coerce string"
-        elif hasattr(x, '_polynomial_'):
-            return x._polynomial_(self)
         return polynomial_element_generic.Polynomial_dense_mod_p(self, x, check, is_gen,construct=construct)
 
Index: sage/rings/polynomial_ring_constructor.py
===================================================================
--- sage/rings/polynomial_ring_constructor.py	(revision 4022)
+++ sage/rings/polynomial_ring_constructor.py	(revision 3667)
@@ -4,5 +4,4 @@
 
 from sage.structure.parent_gens import normalize_names
-from sage.structure.element import is_Element
 import ring
 import weakref
@@ -116,10 +115,4 @@
         y^2 + y
 
-    Often the quotes are not needed, because of predefined symbolic variables:
-        sage: R = GF(9,a)[x]
-        sage: R
-        Univariate Polynomial Ring in x over Finite Field in a of size 3^2
-
-
     In fact, since the diamond brackets on the left determine the variable name, you can omit the
     variable from the square brackets:
@@ -198,10 +191,4 @@
     """
     import polynomial_ring as m
-
-    if is_Element(arg1) and not isinstance(arg1, (int, long, m.integer.Integer)):
-        arg1 = str(arg1)
-    if is_Element(arg2) and not isinstance(arg2, (int, long, m.integer.Integer)):
-        arg2 = str(arg2)
-
     if isinstance(arg1, (int, long, m.integer.Integer)):
         arg1, arg2 = arg2, arg1
@@ -219,8 +206,4 @@
 
     R = None
-    if isinstance(arg1, (list, tuple)):
-        arg1 = [repr(x) for x in arg1]
-    if isinstance(arg2, (list, tuple)):
-        arg2 = [repr(x) for x in arg2]
     if isinstance(arg2, (int, long, m.integer.Integer)):
         # 3. PolynomialRing(base_ring, names, n, order='degrevlex'):
@@ -231,5 +214,5 @@
         R = _multi_variate(base_ring, names, n, sparse, order)
 
-    elif isinstance(arg1, str) or (isinstance(arg1, (list,tuple)) and len(arg1) == 1):
+    elif isinstance(arg1, str) or len(arg1) == 1:
         if not ',' in arg1:
             # 1. PolynomialRing(base_ring, name, sparse=False):
Index: sage/rings/polynomial_singular_interface.py
===================================================================
--- sage/rings/polynomial_singular_interface.py	(revision 4067)
+++ sage/rings/polynomial_singular_interface.py	(revision 2641)
@@ -4,9 +4,4 @@
 AUTHORS:
      -- Martin Albrecht <malb@informatik.uni-bremen.de> (2006-04-21)
-
-TESTS:
-    sage: R = MPolynomialRing(GF(2**8,'a'),10,'x', order='revlex')
-    sage: R == loads(dumps(R))
-    True
 
 """
@@ -35,6 +30,4 @@
 from complex_field import is_ComplexField
 from real_mpfr import is_RealField
-from complex_double import is_ComplexDoubleField
-from real_double import is_RealDoubleField
 from integer_ring import ZZ
 import sage.rings.arith
@@ -171,5 +164,5 @@
             #  size_t bits = 1 + (size_t) ((float)digits * 3.5);
             precision = self.base_ring().precision()
-            digits = sage.rings.arith.integer_ceil((2*precision - 2)/7.0)
+            digits = sage.rings.arith.ceil((2*precision - 2)/7.0)
             self.__singular = singular.ring("(real,%d,0)"%digits, _vars, order=order)
 
@@ -178,16 +171,6 @@
             #  size_t bits = 1 + (size_t) ((float)digits * 3.5);
             precision = self.base_ring().precision()
-            digits = sage.rings.arith.integer_ceil((2*precision - 2)/7.0)
+            digits = sage.rings.arith.ceil((2*precision - 2)/7.0)
             self.__singular = singular.ring("(complex,%d,0,I)"%digits, _vars,  order=order)
-
-        elif is_RealDoubleField(self.base_ring()):
-            # singular converts to bits from base_10 in mpr_complex.cc by:
-            #  size_t bits = 1 + (size_t) ((float)digits * 3.5);
-            self.__singular = singular.ring("(real,15,0)", _vars, order=order)
-
-        elif is_ComplexDoubleField(self.base_ring()):
-            # singular converts to bits from base_10 in mpr_complex.cc by:
-            #  size_t bits = 1 + (size_t) ((float)digits * 3.5);
-            self.__singular = singular.ring("(complex,15,0,I)", _vars,  order=order)
 
         elif self.base_ring().is_prime_field() or (self.base_ring() is ZZ and force):
@@ -219,6 +202,4 @@
                  or is_RealField(base_ring)
                  or is_ComplexField(base_ring)
-                 or is_RealDoubleField(base_ring)
-                 or is_ComplexDoubleField(base_ring)
                  or base_ring is ZZ )
 
Index: sage/rings/power_series_ring.py
===================================================================
--- sage/rings/power_series_ring.py	(revision 4061)
+++ sage/rings/power_series_ring.py	(revision 3663)
@@ -30,14 +30,5 @@
     Power Series Ring in t2 over Power Series Ring in t over Integer Ring
     sage: S.base_ring()
-    Power Series Ring in t over Integer Ring
-
-We compute with power series over the symbolic ring.
-    sage: K.<t> = PowerSeriesRing(SR, 5)
-    sage: f = a + b*t + c*t^2 + O(t^3)
-    sage: f*f
-    a^2 + ((b + a)^2 - b^2 - a^2)*t + ((c + b + a)^2 - (c + b)^2 - (b + a)^2 + 2*b^2)*t^2 + O(t^3)
-    sage: f = sqrt(2) + sqrt(3)*t + O(t^3)
-    sage: f^2
-    2 + ((sqrt(3) + sqrt(2))^2 - 5)*t + 3*t^2 + O(t^3)
+    Power Series Ring in t over Integer Ring            
 
 Elements are first coerced to constants in base_ring, then coerced into the
@@ -65,14 +56,4 @@
     -- William Stein: the code
     -- Jeremy Cho (2006-05-17): some examples (above)
-
-TESTS:
-    sage: R.<t> = PowerSeriesRing(QQ)
-    sage: R == loads(dumps(R))
-    True
-
-    sage: R.<x> = PowerSeriesRing(QQ, sparse=True)
-    sage: R == loads(dumps(R))
-    True
-
 """
 
@@ -123,5 +104,5 @@
         Traceback (most recent call last):
         ...
-        ValueError: first letter of variable name must be a letter
+        TypeError: illegal variable name
 
         sage: S = PowerSeriesRing(QQ, 'x', default_prec = 15); S
@@ -130,6 +111,4 @@
         15
     """
-    if isinstance(name, (int,long,integer.Integer)):
-        default_prec = name
     if not names is None:
         name = names
Index: sage/rings/power_series_ring_element.py
===================================================================
--- sage/rings/power_series_ring_element.py	(revision 4065)
+++ sage/rings/power_series_ring_element.py	(revision 3686)
@@ -86,11 +86,9 @@
 import sage.structure.coerce
 import rational_field, integer_ring
-from integer import Integer
-from integer_mod_ring import IntegerModRing
 import sage.libs.pari.all as pari
 import sage.misc.latex as latex
 from sage.libs.all import PariError
 from sage.misc.functional import sqrt, log
-from math import ceil
+from sage.rings.arith import ceil
 
 Polynomial = polynomial.Polynomial_generic_dense
@@ -368,8 +366,8 @@
             coeffs.sort()
             for (n, x) in coeffs:
-                if x:
+                if x != 0:
                     if s != ' ':
                         s += " + "
-                    x = repr(x)
+                    x = str(x)
                     if not atomic_repr and n > 0 and (x.find("+") != -1 or x.find("-") != -1):
                         x = "(%s)"%x
@@ -387,8 +385,8 @@
             for n in xrange(m):
                 x = v[n]
-                if x:
+                if x != 0:
                     if not first:
                         s += " + "
-                    x = repr(x)
+                    x = str(x)
                     if not atomic_repr and n > 0 and (x[1:].find("+") != -1 or x[1:].find("-") != -1):
                         x = "(%s)"%x
@@ -458,5 +456,5 @@
                     s += "%s|%s"%(x,var)
                 else:
-                    s += repr(x)
+                    s += str(x)
                 first = False
 
@@ -524,5 +522,5 @@
         EXAMPLES:
             sage: R.<m> = CDF[[]]
-            sage: f = CDF(pi)^2 + m^3 + CDF(e)*m^4 + O(m^10); f
+            sage: f = pi^2 + m^3 + e*m^4 + O(m^10); f
             9.86960440109 + 1.0*m^3 + 2.71828182846*m^4 + O(m^10)
             sage: f[-5]
@@ -605,7 +603,7 @@
         return self._mul_(right, prec)
 
-    def __nonzero__(self):
-        """
-        Return True if this power series doesn't equal 0.
+    def is_zero(self):
+        """
+        Return True if this power series equals 0.
 
         EXAMPLES:
@@ -622,5 +620,5 @@
             True
         """
-        return not self.polynomial().is_zero()
+        return self.polynomial().is_zero()
 
     def is_unit(self):
@@ -824,14 +822,10 @@
 
     def __mod__(self, other):
-        """
-        EXAMPLES:
-            sage: R.<T> = Qp(7)[[]]
-            sage: f = (48*67 + 46*67^2)*T + (1 + 42*67 + 5*67^3)*T^2 + O(T^3)
-            sage: f % 67
-            T^2 + O(T^3)
-        """
         if isinstance(other,(int,Integer,long)):
-            return power_series_ring.PowerSeriesRing(IntegerModRing(other), self.variable())(self)
-        raise NotImplementedError, "Mod on power series ring elements not defined except modulo an integer."
+            try:
+                return power_series_ring.PowerSeriesRing(Zmod(other))(self)
+            except TypeError:
+                raise ZeroDivisionError
+        raise NotImplementedError, "Mod on power series ring not defined."
     
     def sqrt(self):
@@ -845,5 +839,5 @@
 
         EXAMPLES:
-            sage: K.<t> = PowerSeriesRing(QQ, 5)
+            sage: K.<t> = PowerSeriesRing(QQ, 't', 5)
             sage: sqrt(t^2)
             t
@@ -852,13 +846,8 @@
             sage: sqrt(4+t)
             2 + 1/4*t - 1/64*t^2 + 1/512*t^3 - 5/16384*t^4 + O(t^5)
-
-        If the constant term is not a square, the result maybe be defined over a different
-        base ring or be symbolic (potentially very very slow!):
-            sage: a = sqrt(2+t+O(t^2)); a
-            sqrt(2) + 1/(2*sqrt(2))*t + O(t^2)
-            sage: parent(a)
-            Power Series Ring in t over Symbolic Ring
+            sage: sqrt(2+t)
+            1.41421356237309 + 0.353553390593274*t - 0.0441941738241592*t^2 + 0.0110485434560399*t^3 - 0.00345266983001233*t^4 + O(t^5)
             
-            sage: K.<t> = PowerSeriesRing(QQ, 50)
+            sage: K.<t> = PowerSeriesRing(QQ, 't', 50)
             sage: sqrt(1+2*t+t^2)
             1 + t + O(t^50)
@@ -885,14 +874,10 @@
 
         a = self.valuation_zero_part()
-        try:
-            x = sqrt(a[0])
-            x = self.base_ring()(x)
-        except TypeError:
-            self = self.change_ring(x.parent())
+        x = sqrt(a[0])
         newp = self.parent().base_extend(x.parent())
         a = newp(a)
         half = ~newp.base_ring()(2)
         
-        for i in range (int(ceil(log(prec, 2)))):
+        for i in range (ceil(log(prec, 2))):
             x = half * (x + a/x)
             
@@ -1193,5 +1178,5 @@
         return self.__f
 
-    def __call__(self, *xs):
+    def __call__(self, x):
         """
         EXAMPLE:
@@ -1201,15 +1186,11 @@
             2        
         """
-        if isinstance(xs[0], tuple):
-            xs = xs[0]
-        x = xs[0]
         try:
             if x.parent() is self.parent():
                 if not (self.prec() is infinity):
                     x = x.add_bigoh(self.prec()*x.valuation())
-                    xs = list(xs); xs[0] = x; xs = tuple(xs) # tuples are immutable
         except AttributeError:
             pass
-        return self.__f(xs)
+        return self.__f(x)
 
     def __setitem__(self, n, value):
@@ -1518,5 +1499,5 @@
         if self.prec() is infinity:
             raise RuntimeError, "series precision must be finite for conversion to pari object."
-        return pari.pari(repr(self))
+        return pari.pari(str(self))
             
 
Index: sage/rings/quotient_ring.py
===================================================================
--- sage/rings/quotient_ring.py	(revision 4059)
+++ sage/rings/quotient_ring.py	(revision 2337)
@@ -4,13 +4,4 @@
 AUTHOR:
     -- William Stein
-
-TESTS:
-    sage: R.<x> = PolynomialRing(ZZ)
-    sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2])
-    sage: S = R.quotient_ring(I);
-    sage: S == loads(dumps(S))
-    True
-
-
 """
 
@@ -66,5 +57,5 @@
     
     EXAMPLES:
-        sage: R.<x> = PolynomialRing(ZZ,'x')
+        sage: R = PolynomialRing(ZZ,'x')
         sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2])
         sage: S = R.quotient_ring(I); S
@@ -145,5 +136,6 @@
         except AttributeError:
             import morphism
-            pi = morphism.RingHomomorphism_cover(self.__R.Hom(self))
+            pi = morphism.RingHomomorphism_cover(self.__R, self)
+            #pi = self.__R.homomorphism(self.__R.gens(), self)       # needlessly slow (!)
             lift = self.lift()
             pi._set_lift(lift)
Index: sage/rings/quotient_ring_element.py
===================================================================
--- sage/rings/quotient_ring_element.py	(revision 4059)
+++ sage/rings/quotient_ring_element.py	(revision 3134)
@@ -80,6 +80,6 @@
         return self.__rep
 
-    def __nonzero__(self):
-        return self.__rep not in self.parent().defining_ideal()
+    def is_zero(self):
+        return self.__rep in self.parent().defining_ideal()
 
     def is_unit(self):
Index: sage/rings/rational.pyx
===================================================================
--- sage/rings/rational.pyx	(revision 4059)
+++ sage/rings/rational.pyx	(revision 3604)
@@ -10,11 +10,4 @@
           and improve behavior of sqrt.
     -- David Harvey (2006-09-15): added nth_root
-
-TESTS:
-    sage: a = -2/3
-    sage: a == loads(dumps(a))
-    True
-
-
 """
 
@@ -191,5 +184,13 @@
                 return
             if not base:
-                set_from_Rational(self, x.simplest_rational())
+                v = x._pari_().contfrac().contfracpnqn()
+                s = '%s/%s'%(hex(v[0,0]), hex(v[1,0]))
+                n = mpq_set_str(self.value, s, 16)
+                # this mpq_denref business is to program around a bug in GMP, where
+                # it doesn't correctly return an error code in mpq_set_str (or canonicalalize)
+                # for strings with a 0 in the denominator.   In fact, it crashes horribly.
+                if n or mpz_cmp_si(mpq_denref(self.value), 0) == 0:
+                    raise TypeError, "unable to convert %s to a rational"%x
+                mpq_canonicalize(self.value)                                    
             else:
                 xstr = x.str(base)
@@ -368,5 +369,5 @@
         return self.numerator().valuation(p) - self.denominator().valuation(p)
     
-    def sqrt_approx(self, bits=None):
+    def sqrt(self, bits=None):
         r"""
         Returns the positive square root of self as a real number to
@@ -385,22 +386,22 @@
         EXAMPLES:
             sage: x = 23/2
-            sage: x.sqrt_approx()
+            sage: x.sqrt()
             3.39116499156263
             sage: x = 32/5
-            sage: x.sqrt_approx()
+            sage: x.sqrt()
             2.52982212813470
             sage: x = 16/9
-            sage: x.sqrt_approx()
+            sage: x.sqrt()
+            4/3
+            sage: x.sqrt(53)
             1.33333333333333
-            sage: x.sqrt_approx(100)
-            1.3333333333333333333333333333
             sage: x = 9837/2
-            sage: x.sqrt_approx()
+            sage: x.sqrt()
             70.1320183653658
             sage: x = 645373/45
-            sage: x.sqrt_approx()
+            sage: x.sqrt()
             119.756512233040
             sage: x = -12/5
-            sage: x.sqrt_approx()
+            sage: x.sqrt()
             1.54919333848297*I
 
@@ -409,4 +410,8 @@
         """
         if bits is None:
+            try:
+                return self.square_root()
+            except ValueError:
+                pass
             bits = max(53, 2*(mpz_sizeinbase(self.value, 2)+2))
             
@@ -418,5 +423,5 @@
             return R(self).sqrt()
 
-    def sqrt(self):
+    def square_root(self):
         r"""
         Return the positive rational square root of self, or raises a
@@ -425,69 +430,23 @@
         EXAMPLES:
             sage: x = 125/5
-            sage: x.sqrt()
+            sage: x.square_root()
             5
             sage: x = 64/4
-            sage: x.sqrt()
+            sage: x.square_root()
             4
             sage: x = 1000/10
-            sage: x.sqrt()
+            sage: x.square_root()
             10
             sage: x = 81/3
-            sage: x.sqrt()
-            3*sqrt(3)
-            sage: x = -81/3
-            sage: x.sqrt()
-            3*sqrt(3)*I
+            sage: x.square_root()
+            Traceback (most recent call last):
+            ...
+            ValueError: self (=27) is not a perfect square
 
         AUTHOR:
-            -- Naqi Jaffery (2006-03-05): some examples
-        """
-        if self < 0:
-            from sage.calculus.calculus import sqrt
-            return sqrt(self)
+            -- Naqi Jaffery (2006-03-05): examples
+        """
         # TODO -- this could be quicker, by using GMP directly.
-        return self.numerator().sqrt() / self.denominator().sqrt()
-
-    def period(self):
-        r"""
-        Return the period of the repeating part of the decimal
-        expansion of this rational number.
-
-        ALGORITHM: When a rational number $n/d$ with $(n,d)==1$ is
-        expanded, the period begins after $s$ terms and has length
-        $t$, where $s$ and $t$ are the smallest numbers satisfying
-        $10^s=10^(s+t) (mod d)$.  When $d$ is coprime to 10, this
-        becomes a purely periodic decimal with $10^t=1 (mod d)$.
-        (Lehmer 1941 and Mathworld).
-
-        EXAMPLES:
-            sage: (1/7).period()
-            6
-            sage: RR(1/7)
-            0.142857142857143
-            sage: (1/8).period()
-            1
-            sage: RR(1/8)
-            0.125000000000000
-            sage: RR(1/6)
-            0.166666666666667
-            sage: (1/6).period()
-            1
-            sage: x = 333/106
-            sage: x.period()
-            13
-            sage: RealField(200)(x)
-            3.1415094339622641509433962264150943396226415094339622641509
-        """
-        cdef unsigned int alpha, beta
-        d = self.denominator()
-        alpha = d.valuation(2)
-        beta = d.valuation(5)
-        P = d.parent()
-        if alpha > 0 or beta > 0:
-            d = d//(P(2)**alpha * P(5)**beta)
-        from sage.rings.integer_mod import Mod
-        a = Mod(P(10),d)
-        return a.multiplicative_order()
+        return self.numerator().square_root() / self.denominator().square_root()
 
     def nth_root(self, int n):
@@ -694,17 +653,8 @@
             32/243
             sage: (-1/1)^(1/3)
-            -1
-
-        We raise to some interesting powers:
-            sage: (2/3)^I
-            2^I/3^I
-            sage: (2/3)^sqrt(2)
-            2^sqrt(2)/3^sqrt(2)
-            sage: (2/3)^(x^n + y^n + z^n)
-            3^(-z^n - y^n - x^n)*2^(z^n + y^n + x^n)
-            sage: (-7/11)^(tan(x)+exp(x))
-            11^(-tan(x) - e^x)*-7^(tan(x) + e^x)
-            sage: (2/3)^(3/4)
-            2^(3/4)/3^(3/4)
+            Traceback (most recent call last):
+            ...
+            TypeError: exponent (=1/3) must be an integer.
+            Coerce your numbers to real or complex numbers first.
         """
         cdef Rational _self, x
@@ -712,23 +662,12 @@
             return self.__pow__(float(n))
         _self = self
+        if n < 0:
+            x = _self**(-n)
+            return x.__invert__()
         cdef unsigned int _n
         try:
             _n = integer.Integer(n)
         except TypeError:
-            if isinstance(n, Rational):
-                # this is the only sensible answer that avoids rounding and
-                # an infinite recursion.
-                from sage.calculus.calculus import SR
-                return SR(self)**SR(n)
-            try:
-                s = n.parent()(self)
-                return s**n
-            except AttributeError:
-                raise TypeError, "exponent (=%s) must be an integer.\nCoerce your numbers to real or complex numbers first."%n
-
-        if n < 0:  # this doesn't make sense unless n is an integer.
-            x = _self**(-n)
-            return x.__invert__()
-
+            raise TypeError, "exponent (=%s) must be an integer.\nCoerce your numbers to real or complex numbers first."%n
         x = <Rational> PY_NEW(Rational)                        
         cdef mpz_t num, den
@@ -755,4 +694,7 @@
         mpq_neg(x.value, self.value)
         return x
+
+    def __nonzero__(self):
+        return not self.numerator().is_zero()
 
     def __abs__(self):
@@ -1104,9 +1046,6 @@
         return bool(mpz_cmp_si(mpq_numref(self.value), 1) == 0)
 
-    def __nonzero__(self):
-        return bool(mpz_cmp_si(mpq_numref(self.value), 0) != 0)
-
-    def is_square(self):
-        return self.numerator().is_square() and self.denominator().is_square()
+    def is_zero(self):
+        return bool(mpz_cmp_si(mpq_numref(self.value), 0) == 0)
     
     cdef _lshift(self, long int exp):
Index: sage/rings/rational_field.py
===================================================================
--- sage/rings/rational_field.py	(revision 4065)
+++ sage/rings/rational_field.py	(revision 3665)
@@ -5,10 +5,4 @@
 (arbitrary precision) rational numbers.  Each rational number is an
 instance of the class \class{Rational}.
-
-TEST:
-   sage: Q = RationalField()
-   sage: Q == loads(dumps(Q))
-   True
-
 """
 
@@ -168,5 +162,5 @@
             sage: t = L/O; t
             0.200000000000000
-            sage: QQ(RealField(45)(t))
+            sage: QQ(t)
             1/5
         """
@@ -216,5 +210,5 @@
         """
 
-        from sage.rings.arith import integer_floor as floor
+        from sage.rings.arith import floor
 
         n=self(0)
@@ -244,11 +238,4 @@
     def ngens(self):
         return 1
-
-    def is_subring(self, K):
-        if K.is_field():
-            return K.characteristic() == 0
-        if K.characteristic() != 0:
-            return False
-        raise NotImplementedError
 
     def is_field(self):
Index: sage/rings/real_double.pxd
===================================================================
--- sage/rings/real_double.pxd	(revision 3725)
+++ sage/rings/real_double.pxd	(revision 3299)
@@ -5,7 +5,4 @@
 from sage.rings.ring cimport Field
 
-cdef extern from "limits.h":
-    int INT_MAX
-    double NAN
 
 cdef class RealDoubleField_class(Field):
Index: sage/rings/real_double.pyx
===================================================================
--- sage/rings/real_double.pyx	(revision 4059)
+++ sage/rings/real_double.pyx	(revision 3649)
@@ -22,5 +22,4 @@
 include '../ext/cdefs.pxi'
 include '../ext/stdsage.pxi'
-include '../ext/random.pxi'
 include '../ext/interrupt.pxi'
 include '../gsl/gsl.pxi'
@@ -33,4 +32,6 @@
 import sage.libs.pari.gen
 
+from random import random
+
 from sage.misc.sage_eval import sage_eval
 
@@ -40,9 +41,4 @@
 import sage.rings.integer
 import sage.rings.rational
-
-from sage.rings.integer cimport Integer
-
-def is_RealDoubleField(x):
-    return bool(PY_TYPE_CHECK(x, RealDoubleField_class))
 
 cdef class RealDoubleField_class(Field):
@@ -117,6 +113,4 @@
             True
         """
-        if hasattr(x, '_real_double_'):
-            return x._real_double_(self)
         return RealDoubleElement(x)
 
@@ -142,6 +136,4 @@
             sage: parent(CDF(5) + RDF(3))
             Complex Double Field
-            sage: CDF.gen(0) + 5.0
-            5.0 + 1.0*I            
         """
         if isinstance(x, (int, long, sage.rings.integer.Integer,
@@ -149,5 +141,6 @@
             return self(x)
         import real_mpfr
-        return self._coerce_try(x, [real_mpfr.RR])
+        return self._coerce_try(x, [sage.functions.constants.ConstantRing,
+                                    real_mpfr.RR])
             
 
@@ -207,5 +200,5 @@
         return x
 
-    def random_element(self, double min=-1, double max=1):
+    def random_element(self, float min=-1, float max=1):
         """
         Return a random element of this real double field in the interval [min, max].
@@ -217,5 +210,5 @@
 	    106.592535785
         """
-        return self._new_c((max-min)*(<double>random())/RAND_MAX + min)
+        return self._new_c((max-min)*random() + min)
     
     def name(self):
@@ -365,5 +358,5 @@
             Real Double Field            
         """
-        return self._parent
+        return RDF
     
     def __repr__(self):
@@ -379,16 +372,9 @@
         return self.str()
 
-    def _latex_(self):
-        s = self.str()
-        parts = s.split('e')
-        if len(parts) > 1:
-            # scientific notation
-            if parts[1][0] == '+':
-                parts[1] = parts[1][1:]
-            s = "%s \\times 10^{%s}" % (parts[0], parts[1])
-        return s
+    def _latex_(self):  # todo -- this is terrible if sci not.
+        return self.str()
 
     def __hash__(self):
-        return hash(float(self))
+        return hash(self.str())
 
     def _im_gens_(self, codomain, im_gens):
@@ -431,4 +417,7 @@
         """
         return self
+        #cdef RealDoubleElement z
+        #z = RealDoubleElement(self._value)
+        #return z
 
     def integer_part(self):
@@ -460,7 +449,5 @@
             -0.266666666667
         """
-        cdef RealDoubleElement x = <RealDoubleElement>PY_NEW(RealDoubleElement)
-        x._value = 1.0 / self._value
-        return x
+        return RealDoubleElement(1/self._value)
     
     cdef ModuleElement _add_c_impl(self, ModuleElement right):    
@@ -472,7 +459,5 @@
             1.0
         """
-        cdef RealDoubleElement x = <RealDoubleElement>PY_NEW(RealDoubleElement)
-        x._value = self._value + (<RealDoubleElement>right)._value
-        return x
+        return self._new_c(self._value + (<RealDoubleElement>right)._value)
         
     cdef ModuleElement _sub_c_impl(self, ModuleElement right):
@@ -484,7 +469,5 @@
             -4.0
         """
-        cdef RealDoubleElement x = <RealDoubleElement>PY_NEW(RealDoubleElement)
-        x._value = self._value - (<RealDoubleElement>right)._value
-        return x
+        return self._new_c(self._value - (<RealDoubleElement>right)._value)
         
     cdef RingElement _mul_c_impl(self, RingElement right):
@@ -496,7 +479,5 @@
             -3.75
         """
-        cdef RealDoubleElement x = <RealDoubleElement>PY_NEW(RealDoubleElement)
-        x._value = self._value * (<RealDoubleElement>right)._value
-        return x
+        return self._new_c(self._value * (<RealDoubleElement>right)._value)
     
     cdef RingElement _div_c_impl(self, RingElement right):
@@ -508,7 +489,5 @@
             inf
         """
-        cdef RealDoubleElement x = <RealDoubleElement>PY_NEW(RealDoubleElement)
-        x._value = self._value / (<RealDoubleElement>right)._value
-        return x
+        return self._new_c(self._value / (<RealDoubleElement>right)._value)
 
     cdef ModuleElement _neg_c_impl(self):
@@ -520,7 +499,5 @@
             1.5
         """
-        cdef RealDoubleElement x = <RealDoubleElement>PY_NEW(RealDoubleElement)
-        x._value = -self._value
-        return x
+        return self._new_c(-self._value)
 
     def __abs__(self):
@@ -667,29 +644,9 @@
         return long(self._value)
 
-    def _complex_mpfr_field_(self, CC):
-        """
-        EXAMPLES:
-            sage: a = RDF(1/3)
-            sage: CC(a)
-            0.333333333333333
-            sage: a._complex_mpfr_field_(CC)
-            0.333333333333333
-
-        If we coerce to a higher-precision field the extra bits appear
-        random; they are actualy 0's in base 2.
-            sage: a._complex_mpfr_field_(ComplexField(100))
-            0.33333333333333331482961625625
-            sage: a._complex_mpfr_field_(ComplexField(100)).str(2)
-            '0.01010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000'
-        """
-        return CC(self._value)
-
-    def _complex_double_(self, CDF):
-        """
-        EXAMPLES:
-            sage: CDF(RDF(1/3))
-            0.333333333333
-        """
-        return CDF(self._value)
+    def _complex_number_(self):
+        return sage.rings.complex_field.ComplexField()(self)
+
+    def _complex_double_(self):
+        return sage.rings.complex_double.ComplexDoubleField()(self)
 
     def _pari_(self):
@@ -748,5 +705,5 @@
             sage: r.sqrt()
             65.9090282131
-            sage: r.sqrt()^2 - r             # random low order bits
+            sage: r.sqrt()^2 - r
             0.0
 
@@ -755,7 +712,7 @@
             1.41421356237*I
             """
-        if self._value >= 0:
+        if self >= 0:
             return self.square_root()
-        return self._complex_double_(sage.rings.complex_double.CDF).sqrt()
+        return self._complex_double_().sqrt()
         
 
@@ -825,5 +782,5 @@
 
     def __pow(self, RealDoubleElement exponent):
-        return self._new_c(gsl_sf_exp(gsl_sf_log(self._value) * exponent._value))
+        return self._new_c(self._value**exponent._value)
 
     def __pow_int(self, int exponent):
@@ -846,25 +803,14 @@
             sage: a^a
             1.29711148178
-
-        Symbolic examples:
-            sage: RDF('-2.3')^(x+y^3+sin(x))
-            -2.30000000000000^(y^3 + sin(x) + x)
-            sage: RDF('-2.3')^x
-            -2.30000000000000^x
         """
         cdef RealDoubleElement x
-        if PY_TYPE_CHECK(exponent, RealDoubleElement):
+        if isinstance(self, RealDoubleElement):
             return self.__pow(RealDoubleElement(exponent))
-        elif PY_TYPE_CHECK(exponent, int):
-            return self.__pow_int(exponent)
-        elif PY_TYPE_CHECK(exponent, Integer) and exponent < INT_MAX:
+        if isinstance(exponent, (int,Integer)):
             return self.__pow_int(int(exponent))
-        try:
-            x = self.parent()(exponent)
-        except TypeError:
-            try:
-                return exponent.parent()(self)**exponent
-            except AttributeError:
-                raise TypeError
+        elif not isinstance(exponent, RealDoubleElement):
+            x = RealDoubleElement(exponent)
+        else:
+            x = exponent
         return self.__pow(x)
 
@@ -937,5 +883,5 @@
             sage: r = RDF('16.0'); r.log10()
             1.20411998266
-            sage: r.log() / RDF(log(10))
+            sage: r.log() / log(10)
             1.20411998266
             sage: r = RDF('39.9'); r.log10()
@@ -954,5 +900,5 @@
             sage: r = RDF(16); r.logpi()
             2.42204624559
-            sage: r.log() / RDF(log(pi))
+            sage: r.log() / log(pi)
             2.42204624559
             sage: r = RDF('39.9'); r.logpi()
@@ -1055,7 +1001,4 @@
         """
         return self._new_c(gsl_sf_sin(self._value))
-        
-    def restrict_angle(self):
-        return self._new_c(gsl_sf_angle_restrict_symm(self._value))
     
     def tan(self):
@@ -1071,7 +1014,7 @@
             0.57735026919
         """
-        cdef double denom
-        cos = gsl_sf_cos(self._value)
-        a = self._new_c(gsl_sf_sin(self._value) / cos)
+        _sig_on
+        a = self._new_c(tan(self._value))
+        _sig_off
         return a
 
@@ -1139,5 +1082,5 @@
             1.0344656401
         """
-        return self._new_c(gsl_ldexp( gsl_sf_exp(self._value) + gsl_sf_exp(-self._value), -1)) # (e^x + x^-x)/2
+        return self._new_c(cosh(self._value))
 
     def sinh(self):
@@ -1148,7 +1091,8 @@
             sage: q = RDF.pi()/12
             sage: q.sinh()
-            0.264800227602            
-        """
-        return self._new_c(gsl_ldexp( gsl_sf_expm1(self._value) - gsl_sf_expm1(-self._value), -1)) # (e^x - x^-x)/2
+            0.264800227602
+            
+        """
+        return self._new_c(sinh(self._value))
 
     def tanh(self):
@@ -1161,5 +1105,5 @@
             0.255977789246
         """
-        return self.sinh() / self.cosh()
+        return self._new_c(tanh(self._value))
 
     def acosh(self):
@@ -1202,40 +1146,4 @@
         return self._new_c(gsl_atanh(self._value))
 
-    def sech(self):
-        r"""
-        This function returns the  hyperbolic secant.
-
-        EXAMPLES:
-            sage: RDF(pi).sech()
-            0.0862667383341
-            sage: CDF(pi).sech()
-            0.0862667383341
-        """
-        return 1/self.cosh()
-
-    def csch(self):
-        r"""
-        This function returns the hyperbolic cosecant.
-
-        EXAMPLES:
-            sage: RDF(pi).csch()
-            0.08658953753
-            sage: CDF(pi).csch()
-            0.08658953753        
-        """
-        return 1/self.sinh()
-
-    def coth(self):
-        r"""
-        This function returns the hyperbolic cotangent. 
-
-        EXAMPLES:
-            sage: RDF(pi).coth()
-            1.0037418732
-            sage: CDF(pi).coth()
-            1.0037418732
-        """
-        return self.cosh() / self.sinh()
-    
     def agm(self, other):
         """
@@ -1345,207 +1253,3 @@
 def is_RealDoubleElement(x):
     return PY_TYPE_CHECK(x, RealDoubleElement)
-    
-    
-    
-    
-
  
-################# FAST CREATION CODE ######################
-########### Based on fast integer creation code   #########
-######## There is nothing to see here, move along   #######
-    
-cdef extern from *:
-    
-    ctypedef struct RichPyObject "PyObject"
- 
-    # We need a PyTypeObject with elements so we can
-    # get and set tp_new, tp_dealloc, tp_flags, and tp_basicsize
-    ctypedef struct RichPyTypeObject "PyTypeObject":
-
-        # We replace this one
-        PyObject*      (*    tp_new) ( RichPyTypeObject*, PyObject*, PyObject*)
-
-        # Not used, may be useful to determine correct memory management function
-        RichPyObject *(*   tp_alloc) ( RichPyTypeObject*, size_t )
-
-        # We replace this one
-        void           (*tp_dealloc) ( PyObject*)
-
-        # Not used, may be useful to determine correct memory management function
-        void          (*    tp_free) ( PyObject* )
-
-        # We set a flag here to circumvent the memory manager
-        long tp_flags 
-
-    cdef long Py_TPFLAGS_HAVE_GC
-
-    # We need a PyObject where we can get/set the refcnt directly
-    # and access the type.
-    ctypedef struct RichPyObject "PyObject":
-        int ob_refcnt
-        RichPyTypeObject* ob_type
-         
-    # Allocation 
-    RichPyObject* PyObject_MALLOC(int)
-
-    # Useful for debugging, see below
-    void PyObject_INIT(RichPyObject *, RichPyTypeObject *)
-
-    # Free
-    void PyObject_FREE(PyObject*)
-
-# We use a global element to steal all the references
-# from.  DO NOT INITIALIZE IT AGAIN and DO NOT REFERENCE IT!
-cdef RealDoubleElement global_dummy_element
-global_dummy_element = RealDoubleElement(0)
-
-# A global pool for performance when elements are rapidly created and destroyed. 
-# It operates on the following principles:
-#
-# - The pool starts out empty. 
-# - When an new element is needed, one from the pool is returned 
-#   if available, otherwise a new Integer object is created
-# - When an element is collected, it will add it to the pool 
-#   if there is room, otherwise it will be deallocated. 
-    
-cdef enum:
-    element_pool_size = 50 # Pyrex has no way of defining constants
-    
-cdef PyObject* element_pool[element_pool_size]
-cdef int element_pool_count = 0
-
-# used for profiling the pool
-cdef int total_alloc = 0
-cdef int use_pool = 0
-
-# The signature of tp_new is 
-# PyObject* tp_new(RichPyTypeObject *t, PyObject *a, PyObject *k). 
-# However we don't actually use any of it.
-#
-# t in this case is the RealDoubleElement TypeObject.
-
-cdef PyObject* fast_tp_new(RichPyTypeObject *t, PyObject *a, PyObject *k):
-
-    global element_pool, element_pool_count, total_alloc, use_pool
-
-    cdef RichPyObject* new
-
-    # for profiling pool usage
-    # total_alloc += 1
-    
-    # If there is a ready integer in the pool, we will 
-    # decrement the counter and return that. 
-
-    if element_pool_count > 0:
-    
-        # for profiling pool usage
-        # use_pool += 1
-        
-        element_pool_count -= 1
-        new = <RichPyObject *> element_pool[element_pool_count]
-      
-    # Otherwise, we have to create one.  
-
-    else:
-
-        # allocate enough room for the Integer, sizeof_Integer is
-        # sizeof(Integer). The use of PyObject_MALLOC directly
-        # assumes that Integers are not garbage collected, i.e. 
-        # they do not pocess references to other Python
-        # objects (Aas indicated by the Py_TPFLAGS_HAVE_GC flag). 
-        # See below for a more detailed description.
-
-        new = PyObject_MALLOC( sizeof(RealDoubleElement) )
-
-        # Now set every member as set in z, the global dummy Integer
-        # created before this tp_new started to operate.
-
-        memcpy(new, (<void*>global_dummy_element), sizeof(RealDoubleElement) )
-
-        # This line is only needed if Python is compiled in debugging
-        # mode './configure --with-pydebug'. If that is the case a Python
-        # object has a bunch of debugging fields which are initialized
-        # with this macro. For speed reasons, we don't call it if Python
-        # is not compiled in debug mode. So uncomment the following line
-        # if you are debugging Python.
-
-        #PyObject_INIT(new, (<RichPyObject*>global_dummy_element).ob_type)
-
-    # The global_dummy_element may have a reference count larger than
-    # one, but it is expected that newly created objects have a
-    # reference count of one. This is potentially unneeded if
-    # everybody plays nice, because the gobal_dummy_Integer has only
-    # one reference in that case.
-    
-    # Objects from the pool have reference count zero, so this
-    # needs to be set in this case. 
-
-    new.ob_refcnt = 1
-
-    return new
-
-cdef void fast_tp_dealloc(PyObject* o):
-
-    # If there is room in the pool for a used integer object, 
-    # then put it in rather than deallocating it. 
-
-    global element_pool, element_pool_count
-    
-    if element_pool_count < element_pool_size:
-            
-        # And add it to the pool. 
-        element_pool[element_pool_count] = o
-        element_pool_count += 1
-        return
-
-    # Free the object. This assumes that Py_TPFLAGS_HAVE_GC is not
-    # set. If it was set another free function would need to be
-    # called.
-
-    PyObject_FREE(o)
-
-hook_fast_tp_functions()
-
-def hook_fast_tp_functions():
-    """
-    """
-    global global_dummy_element
-
-    cdef long flag
-
-    cdef RichPyObject* o
-    o = <RichPyObject*>global_dummy_element
-
-    # By default every object created in Pyrex is garbage
-    # collected. This means it may have references to other objects
-    # the Garbage collector has to look out for. We remove this flag
-    # as the only reference an Integer has is to the global Integer
-    # ring. As this object is unique we don't need to garbage collect
-    # it as we always have a module level reference to it. If another
-    # attribute is added to the Integer class this flag removal so as
-    # the alloc and free functions may not be used anymore.
-    # This object will still be reference counted. 
-    flag = Py_TPFLAGS_HAVE_GC
-    o.ob_type.tp_flags = <long>(o.ob_type.tp_flags & (~flag))
-
-    # Finally replace the functions called when an Integer needs
-    # to be constructed/destructed.
-    o.ob_type.tp_new = &fast_tp_new
-    o.ob_type.tp_dealloc = &fast_tp_dealloc
-
-def time_alloc_list(n):
-    cdef int i
-    l = []
-    for i from 0 <= i < n:
-        l.append(PY_NEW(RealDoubleElement))
-
-    return l
-
-def time_alloc(n):
-    cdef int i
-    for i from 0 <= i < n:
-        z = PY_NEW(RealDoubleElement)
-
-def pool_stats():
-    print "Used pool %s / %s times" % (use_pool, total_alloc)
-    print "Pool contains %s / %s items" % (integer_pool_count, integer_pool_size)
Index: sage/rings/real_mpfi.pxd
===================================================================
--- sage/rings/real_mpfi.pxd	(revision 3716)
+++ sage/rings/real_mpfi.pxd	(revision 2633)
@@ -10,7 +10,4 @@
 cimport sage.structure.element
 from sage.structure.element cimport RingElement
-
-from rational import Rational
-from rational cimport Rational
 
 cimport real_mpfr
@@ -46,3 +43,3 @@
 
     cdef RealIntervalFieldElement abs(RealIntervalFieldElement self)
-    cdef Rational _simplest_rational_helper(self)    
+    
Index: sage/rings/real_mpfi.pyx
===================================================================
--- sage/rings/real_mpfi.pyx	(revision 4059)
+++ sage/rings/real_mpfi.pyx	(revision 3478)
@@ -140,4 +140,7 @@
 from integer import Integer
 from integer cimport Integer
+
+from rational import Rational
+from rational cimport Rational
 
 from real_double import RealDoubleElement
@@ -1492,106 +1495,4 @@
 #         return sage.libs.pari.all.pari.new_with_bits_prec(str(self), (<RealIntervalField>self._parent).__prec)
         
-    def simplest_rational(self, low_open=False, high_open=False):
-        """
-        Returns the simplest rational in this interval.
-        Given rationals a/b and c/d (both in lowest terms), the former
-        is simpler if b<d or if b==d and |a|<|c|.
-
-        If optional parameters low_open or high_open are true, then
-        treat this as an open interval on that end.
-
-        EXAMPLES:
-            sage: RealIntervalField(10)(pi).simplest_rational()
-            22/7
-            sage: RealIntervalField(20)(pi).simplest_rational()
-            355/113
-            sage: RIF(0.123, 0.567).simplest_rational()
-            1/2
-            sage: RIF(RR(1/3).nextabove(), RR(3/7)).simplest_rational()
-            2/5
-            sage: RIF(1234/567).simplest_rational()
-            1234/567
-            sage: RIF(-8765/432).simplest_rational()
-            -8765/432
-            sage: RIF(-1.234, 0.003).simplest_rational()
-            0
-            sage: RIF(RR(1/3)).simplest_rational()
-            6004799503160661/18014398509481984
-            sage: RIF(RR(1/3)).simplest_rational(high_open=True)
-            Traceback (most recent call last):
-            ...
-            ValueError: simplest_rational() on open, empty interval
-            sage: RIF(1/3, 1/2).simplest_rational()
-            1/2
-            sage: RIF(1/3, 1/2).simplest_rational(high_open=True)
-            1/3
-            sage: phi = ((RealIntervalField(500)(5).sqrt() + 1)/2)
-            sage: phi.simplest_rational() == fibonacci(362)/fibonacci(361)
-            True
-            
-        """
-        if mpfr_equal_p(&self.value.left, &self.value.right):
-            if low_open or high_open:
-                raise ValueError, 'simplest_rational() on open, empty interval'
-            return self.lower().exact_rational()
-            
-        if mpfi_has_zero(self.value):
-            return Rational(0)
-
-        if mpfi_is_neg(self.value):
-            return -(self._neg_c_impl().simplest_rational(low_open=high_open, high_open=low_open))
-
-        low = self.lower()
-        high = self.upper()
-
-        # First, we try using approximate arithmetic of slightly higher
-        # precision.
-        cdef RealIntervalFieldElement highprec
-        highprec = RealIntervalField(int(self.prec() * 1.2))(self)
-
-        cdef Rational try1 = highprec._simplest_rational_helper()
-        
-        # Note that to compute "try1 >= low", SAGE converts try1 to a
-        # floating-point number rounding down, and "try1 <= high"
-        # rounds up (since "low" and "high" are in downward-rounding
-        # and upward-rounding fields, respectively).
-        if try1 >= low and try1 <= high:
-            ok = True
-            if low_open and (try1 == low.exact_rational()):
-                ok = False
-            if high_open and (try1 == high.exact_rational()):
-                ok = False
-            if ok:
-                return try1
-
-        # We could try again with higher precision; instead, we
-        # go directly to using exact arithmetic.
-        return _simplest_rational_exact(low.exact_rational(),
-                                        high.exact_rational(),
-                                        low_open,
-                                        high_open)
-
-    cdef Rational _simplest_rational_helper(self):
-        """
-        Returns the simplest rational in an interval which is
-        either equal to or slightly larger than self.  We assume
-        that both endpoints of self are nonnegative.
-        """
-
-        low = self.lower()
-
-        cdef RealIntervalFieldElement new_elt
-
-        if low <= 1:
-            if low == 0:
-                return Rational(0)
-            if self.upper() >= 1:
-                return Rational(1)
-            new_elt = ~self
-            return ~(new_elt._simplest_rational_helper())
-
-        fl = low.floor()
-        new_elt = self - fl
-        return fl + new_elt._simplest_rational_helper()
 
     ###########################################
@@ -1859,5 +1760,5 @@
             return bool(mpfi_is_inside_fr(<mpfr_t> other_rn.value, self.value))
         try:
-            other_intv = self._parent(other)
+            other_intv = self._parent._coerce_(other)
             return bool(mpfi_is_inside(other_intv.value, self.value))
         except TypeError, msg:
@@ -1886,5 +1787,5 @@
         else:
             # Let type errors from _coerce_ propagate...
-            other_intv = self._parent(other)
+            other_intv = self._parent._coerce_(other)
 
         mpfi_intersect(x.value, self.value, other_intv.value)
@@ -1922,5 +1823,5 @@
         else:
             # Let type errors from _coerce_ propagate...
-            other_intv = self._parent(other)
+            other_intv = self._parent._coerce_(other)
             mpfi_union(x.value, self.value, other_intv.value)
         return x
@@ -2105,5 +2006,5 @@
             sage: r = RIF(16.0); r.log10()
             [1.2041199826559245 ... 1.2041199826559248]
-            sage: r.log() / log(10.0)
+            sage: r.log() / log(10)
             [1.2041199826559245 ... 1.2041199826559251]
 
@@ -2520,5 +2421,5 @@
         we're much more likely to get the right answer, even if the interval
         is very imprecise.
-            sage: r = r.union(sqrt(2.0))
+            sage: r = r.union(sqrt(2))
             sage: r.algdep(5)
             x^2 - 2
@@ -2641,75 +2542,6 @@
 
 
-def _simplest_rational_test_helper(low, high, low_open=False, high_open=False):
-    """
-    Call _simplest_rational_exact().  Only used to allow doctests
-    on that function.
-    """
-    return _simplest_rational_exact(low, high, low_open, high_open)
-
-cdef _simplest_rational_exact(Rational low, Rational high, int low_open, int high_open):
-    """
-    Return the simplest rational between low and high.  May return low
-    or high unless low_open or high_open (respectively) are true (non-zero).
-    We assume that low and high are both nonnegative, and that high>low.
-
-    This is a helper function for simplest_rational() on RealIntervalField,
-    and should not be called directly.
-
-    EXAMPLES:
-        sage: test = sage.rings.real_mpfi._simplest_rational_test_helper
-        sage: test(1/4, 1/3, 0, 0)
-        1/3
-        sage: test(1/4, 1/3, 0, 1)
-        1/4
-        sage: test(1/4, 1/3, 1, 1)
-        2/7
-        sage: test(QQ(0), QQ(2), 0, 0)
-        0
-        sage: test(QQ(0), QQ(2), 1, 0)
-        1
-        sage: test(QQ(0), QQ(1), 1, 0)
-        1
-        sage: test(QQ(0), QQ(1), 1, 1)
-        1/2
-        sage: test(1233/1234, QQ(1), 0, 0)
-        1
-        sage: test(1233/1234, QQ(1), 0, 1)
-        1233/1234
-        sage: test(10000/32007, 10001/32007, 0, 0)
-        289/925
-        sage: test(QQ(0), 1/3, 1, 0)
-        1/3
-        sage: test(QQ(0), 1/3, 1, 1)
-        1/4
-        sage: test(QQ(0), 2/5, 1, 0)
-        1/3
-        sage: test(QQ(0), 2/5, 1, 1)
-        1/3
-    """
-    cdef Rational r
-
-    if low < 1:
-        if low == 0:
-            if low_open:
-                if high > 1:
-                    return Rational(1)
-                inv_high = ~high
-                if high_open:
-                    return ~Rational(inv_high.floor() + 1)
-                else:
-                    return ~Rational(inv_high.ceil())
-            else:
-                return Rational(0)
-
-        if high > 1:
-            return Rational(1)
-
-        r = _simplest_rational_exact(~high, ~low, high_open, low_open)
-        return ~r
-
-    fl = low.floor()
-    return fl + _simplest_rational_exact(low - fl, high - fl, low_open, high_open)
-                
+RR = RealIntervalField()
+
 
 def RealInterval(s, upper=None, int base=10, int pad=0, min_prec=53):
Index: sage/rings/real_mpfr.pyx
===================================================================
--- sage/rings/real_mpfr.pyx	(revision 4059)
+++ sage/rings/real_mpfr.pyx	(revision 3649)
@@ -48,5 +48,4 @@
 include '../ext/interrupt.pxi'
 include "../ext/stdsage.pxi"
-include "../ext/random.pxi"
 
 cimport sage.rings.ring
@@ -217,4 +216,8 @@
         """
         if hasattr(x, '_mpfr_'):
+            # This design with the hasattr is very annoying.
+            # The only thing that uses it right now is symbolic constants
+            # and symbolic function evaluation.
+            # Getting rid of this would speed things up.
             return x._mpfr_(self)
         cdef RealNumber z
@@ -243,7 +246,6 @@
         elif self.__prec <= 53 and is_RealDoubleElement(x):
             return self(x)
-        raise TypeError
-        #import sage.functions.constants
-        #return self._coerce_try(x, [sage.functions.constants.ConstantRing])
+        import sage.functions.constants
+        return self._coerce_try(x, [sage.functions.constants.ConstantRing])
 
     def __cmp__(self, other):
@@ -409,25 +411,8 @@
             0.69314718055994530941723212146
         """
-        cdef RealNumber x = self._new()
+        cdef RealNumber x
+        x = self._new()        
         mpfr_const_log2(x.value, self.rnd)
         return x
-        
-    def random_element(self, min=-1, max=1, distribution=None):
-        """
-        Returns a uniformly distributed random number between 
-        min and max (default -1 to 1). 
-        
-        EXAMPLES:
-            sage: RealField(100).random_element(-5, 10)
-            4.2682457657074627882421620493
-            sage: RealField(10).random_element()
-            .27
-        """
-        cdef RealNumber x = self._new()
-        mpfr_urandomb(x.value, state)
-        if min == 0 and max == 1:
-            return x
-        else:
-            return (max-min)*x + min
 
     def factorial(self, int n):
@@ -678,12 +663,5 @@
 
     def _latex_(self):
-        s = self.str()
-        parts = s.split('e')
-        if len(parts) > 1:
-            # scientific notation
-            if parts[1][0] == '+':
-                parts[1] = parts[1][1:]
-            s = "%s \\times 10^{%s}" % (parts[0], parts[1])
-        return s
+        return str(self)
 
     def _interface_init_(self):
@@ -893,7 +871,10 @@
             100000000000000000
         """
-        cdef Integer z = Integer()
-        mpfr_get_z(z.value, self.value, GMP_RNDZ)
-        return z
+        s = self.str(base=32, no_sci=True)
+        i = s.find(".")
+        if i != -1:
+            return Integer(s[:i], base=32)
+        else:
+            return Integer(s, base=32)
 
     ########################
@@ -1390,193 +1371,4 @@
         return gen
 
-    def exact_rational(self):
-        """
-        Returns the exact rational representation of this floating-point
-        number.
-
-        EXAMPLES:
-            sage: RR(0).exact_rational()
-            0
-            sage: RR(1/3).exact_rational()
-            6004799503160661/18014398509481984
-            sage: RR(37/16).exact_rational()
-            37/16
-            sage: RR(3^60).exact_rational()
-            42391158275216203520420085760
-            sage: RR(3^60).exact_rational() - 3^60
-            6125652559
-            sage: RealField(5)(-pi).exact_rational()
-            -25/8
-        """
-        cdef Integer mantissa = Integer()
-        cdef mp_exp_t exponent
-
-        if not mpfr_number_p(self.value):
-            raise ValueError, 'Calling exact_rational() on infinity or NaN'
-
-        exponent = mpfr_get_z_exp(mantissa.value, self.value)
-
-        return Rational(mantissa) * Integer(2) ** exponent
-        
-    def simplest_rational(self):
-        """
-        Returns the simplest rational which is equal to self (in the SAGE
-        sense).  Recall that SAGE defines the equality operator by
-        coercing both sides to a single type and then comparing;
-        thus, this finds the simplest rational which (when coerced to
-        this RealField) is equal to self.
-
-        Given rationals a/b and c/d (both in lowest terms), the former
-        is simpler if b<d or if b==d and |a|<|c|.
-        
-        The effect of rounding modes is slightly counter-intuitive.
-        Consider the case of round-toward-minus-infinity.  This rounding
-        is performed when coercing a rational to a floating-point
-        number; so the simplest_rational() of a round-to-minus-infinity
-        number will be either exactly equal to or slightly larger than
-        the number.
-
-        EXAMPLES:
-            sage: RRd = RealField(53, rnd='RNDD')
-            sage: RRz = RealField(53, rnd='RNDZ')
-            sage: RRu = RealField(53, rnd='RNDU')
-            sage: def check(x):
-            ...       rx = x.simplest_rational()
-            ...       assert(x == rx)
-            ...       return rx
-            sage: RRd(1/3) < RRu(1/3)
-            True
-            sage: check(RRd(1/3))
-            1/3
-            sage: check(RRu(1/3))
-            1/3
-            sage: check(RRz(1/3))
-            1/3
-            sage: check(RR(1/3))
-            1/3
-            sage: check(RRd(-1/3))
-            -1/3
-            sage: check(RRu(-1/3))
-            -1/3
-            sage: check(RRz(-1/3))
-            -1/3
-            sage: check(RR(-1/3))
-            -1/3
-            sage: check(RealField(20)(pi))
-            355/113
-            sage: check(RR(pi))
-            245850922/78256779
-            sage: check(RR(2).sqrt())
-            131836323/93222358
-            sage: check(RR(1/2^210))
-            1/1645504557321205859467264516194506011931735427766374553794641921
-            sage: check(RR(2^210))
-            1645504557321205950811116849375918117252433820865891134852825088
-            sage: (RR(17).sqrt()).simplest_rational()^2 - 17
-            -1/348729667233025
-            sage: (RR(23).cube_root()).simplest_rational()^3 - 23
-            -1404915133/264743395842039084891584
-            sage: RRd5 = RealField(5, rnd='RNDD')
-            sage: RRu5 = RealField(5, rnd='RNDU')
-            sage: RR5 = RealField(5)
-            sage: below1 = RR5(1).nextbelow()
-            sage: check(RRd5(below1))
-            31/32
-            sage: check(RRu5(below1))
-            16/17
-            sage: check(below1)
-            21/22
-            sage: below1.exact_rational()
-            31/32
-            sage: above1 = RR5(1).nextabove()
-            sage: check(RRd5(above1))
-            10/9
-            sage: check(RRu5(above1))
-            17/16
-            sage: check(above1)
-            12/11
-            sage: above1.exact_rational()
-            17/16
-            sage: check(RR(1234))
-            1234
-            sage: check(RR5(1234))
-            1185
-            sage: check(RR5(1184))
-            1120
-            sage: RRd2 = RealField(2, rnd='RNDD')
-            sage: RRu2 = RealField(2, rnd='RNDU')
-            sage: RR2 = RealField(2)
-            sage: check(RR2(8))
-            7
-            sage: check(RRd2(8))
-            8
-            sage: check(RRu2(8))
-            7
-            sage: check(RR2(13))
-            11
-            sage: check(RRd2(13))
-            12
-            sage: check(RRu2(13))
-            13
-            sage: check(RR2(16))
-            14
-            sage: check(RRd2(16))
-            16
-            sage: check(RRu2(16))
-            13
-            sage: check(RR2(24))
-            21
-            sage: check(RRu2(24))
-            17
-            sage: check(RR2(-24))
-            -21
-            sage: check(RRu2(-24))
-            -24
-        """
-        if mpfr_zero_p(self.value):
-            return Rational(0)
-
-        from real_mpfi import RealIntervalField
-
-        cdef mp_rnd_t rnd = (<RealField>self._parent).rnd
-        cdef int prec = (<RealField>self._parent).__prec
-
-        cdef RealNumber low, high
-        cdef int odd
-
-        if rnd == GMP_RNDN:
-            # hp == "high precision"
-            hp_field = RealField(prec + 1)
-            hp_val = hp_field(self)
-            hp_intv_field = RealIntervalField(prec + 1)
-            low = hp_val.nextbelow()
-            high = hp_val.nextabove()
-            hp_intv = hp_intv_field(low, high)
-            # In GMP_RNDN mode, we round to nearest, preferring even mantissas
-            # if we are exactly halfway between representable floats.
-            # Thus, the values low and high will round to self iff the
-            # mantissa of self is even.  (Note that this only matters
-            # if low or high is an integer; if they are not integers,
-            # then self is simpler than either low or high.)
-            # Is there a better (faster) way to check this?
-            odd = self._parent(low) != self
-            return hp_intv.simplest_rational(low_open=odd, high_open=odd)
-
-        if rnd == GMP_RNDZ:
-            if mpfr_sgn(self.value) > 0:
-                rnd = GMP_RNDD
-            else:
-                rnd = GMP_RNDU
-
-        intv_field = RealIntervalField(prec)
-
-        if rnd == GMP_RNDD:
-            intv = intv_field(self, self.nextabove())
-            return intv.simplest_rational(high_open = True)
-        if rnd == GMP_RNDU:
-            intv = intv_field(self.nextbelow(), self)
-            return intv.simplest_rational(low_open = True)
-        
-
     ###########################################
     # Comparisons: ==, !=, <, <=, >, >=
@@ -1662,12 +1454,11 @@
 
     def sqrt(self):
-        r"""
+        """
         Return a square root of self.
 
         If self is negative a complex number is returned.
 
-        If you use \code{self.sqrt_approx()} then a real number will
-        always be returned (though it will be NaN if self is
-        negative).
+        If you use self.square_root() then a real number will always
+        be returned (though it will be NaN if self is negative).
 
         EXAMPLES:
@@ -1680,11 +1471,9 @@
             sage: r = 4344
             sage: r.sqrt()
-            2*sqrt(1086)
-            
-            sage: r = 4344.0
+            65.9090282131363
             sage: r.sqrt()^2 == r
             True
             sage: r.sqrt()^2 - r            
-            0.000000000000000
+             0.000000000000000
 
             sage: r = -2.0
@@ -1693,8 +1482,9 @@
             """
         if self >= 0:
-            return self.sqrt_approx()
+            return self.square_root()
         return self._complex_number_().sqrt()
-
-    def sqrt_approx(self):
+        
+
+    def square_root(self):
         """
         Return a square root of self.  A real number will always be
@@ -1705,5 +1495,5 @@
         EXAMPLES:
             sage: r = -2.0
-            sage: r.sqrt_approx()
+            sage: r.square_root()
             NaN
             sage: r.sqrt()
@@ -1766,10 +1556,4 @@
             1.0000000*I                    # 32-bit
             -1.0842022e-19 + 1.0000000*I   # 64-bit
-
-        We raise a real number to a symbolic object:
-            sage: 1.5^x
-            1.50000000000000^x
-            sage: -2.3^(x+y^3+sin(x))
-            -2.30000000000000^(y^3 + sin(x) + x)
         """
         cdef RealNumber x
@@ -1777,12 +1561,6 @@
             return self.__pow__(float(exponent))
         if not PY_TYPE_CHECK(exponent, RealNumber):
-            try:
-                x = self
-                exponent = x._parent(exponent)
-            except TypeError:
-                try:
-                    return exponent.parent()(self)**exponent
-                except AttributeError:
-                    raise TypeError
+            x = self
+            exponent = x._parent(exponent)
         return self.__pow(exponent)
 
@@ -2119,28 +1897,4 @@
         return x
 
-    def coth(self):
-        """
-        EXAMPLES:
-            sage: RealField(100)(2).coth()
-            1.0373147207275480958778097648
-        """
-        return 1/self.tanh()
-
-    def csch(self):
-        """
-        EXAMPLES:
-            sage: RealField(100)(2).csch()
-            0.27572056477178320775835148216
-        """
-        return 1/self.sinh()
-
-    def sech(self):
-        """
-        EXAMPLES:
-            sage: RealField(100)(2).sech()
-            0.26580222883407969212086273982        
-        """
-        return 1/self.cosh()
-
     def acosh(self):
         """
@@ -2303,5 +2057,5 @@
 
         EXAMPLE:
-             sage: r = sqrt(2.0); r
+             sage: r = sqrt(2); r
              1.41421356237310
              sage: r.algdep(5)
@@ -2320,5 +2074,5 @@
 
          EXAMPLE:
-              sage: r = sqrt(2.0); r
+              sage: r = sqrt(2); r
               1.41421356237310
               sage: r.algdep(5)
@@ -2420,8 +2174,8 @@
 
 def is_RealField(x):
-    return bool(PY_TYPE_CHECK(x, RealField))
+    return PY_TYPE_CHECK(x, RealField)
 
 def is_RealNumber(x):
-    return bool(PY_TYPE_CHECK(x, RealNumber))
+    return PY_TYPE_CHECK(x, RealNumber)
 
 def __create__RealField_version0(prec, sci_not, rnd):
Index: sage/rings/ring.pxd
===================================================================
--- sage/rings/ring.pxd	(revision 4057)
+++ sage/rings/ring.pxd	(revision 3443)
@@ -5,5 +5,4 @@
     cdef public object _zero_ideal
     cdef public object _unit_ideal
-    cdef _an_element_c_impl(self)
 
 cdef class CommutativeRing(Ring):
Index: sage/rings/ring.pyx
===================================================================
--- sage/rings/ring.pyx	(revision 4057)
+++ sage/rings/ring.pyx	(revision 3649)
@@ -129,7 +129,4 @@
               "in Python, and has the wrong precedence."
 
-    cdef _an_element_c_impl(self):  # override this in SageX
-        return self.zero_element()
-    
     def base_extend(self, R):
         """
Index: sage/rings/sparse_poly.pyx
===================================================================
--- sage/rings/sparse_poly.pyx	(revision 4059)
+++ sage/rings/sparse_poly.pyx	(revision 1793)
@@ -131,5 +131,5 @@
         raise NotImplementedError
 
-    def __nonzero__(self):
+    def is_zero(self):
         raise NotImplementedError
 
Index: sage/schemes/elliptic_curves/ell_generic.py
===================================================================
--- sage/schemes/elliptic_curves/ell_generic.py	(revision 4058)
+++ sage/schemes/elliptic_curves/ell_generic.py	(revision 3390)
@@ -204,83 +204,5 @@
 
     def _magma_init_(self):
-        return 'EllipticCurve([%s])'%(','.join([x._magma_init_() for x in self.ainvs()]))
-
-    def _symbolic_(self, SR):
-        r"""
-        Many elliptic curves can be converted into a symbolic expression
-        using the \code{symbolic_expression} command. 
-        
-        EXAMPLES:
-        We find a torsion point on 11a.
-            sage: E = EllipticCurve('11a')
-            sage: E.torsion_subgroup().gens()
-            ((5 : 5 : 1),)
-
-        We find the corresponding symbolic equality:
-            sage: eqn = symbolic_expression(E); eqn
-            (y^2 + y) == (x^3 - x^2 - 10*x - 20)
-            sage: print eqn
-                                      2        3    2
-                                     y  + y == x  - x  - 10 x - 20
-
-        We verify that the given point is on the curve:
-            sage: eqn(x=5,y=5)
-            (30) == (30)
-            sage: bool(eqn(x=5,y=5))
-            True
-
-        We create a single expression:
-            sage: F = eqn.lhs() - eqn.rhs(); print F
-                                      2        3    2
-                                     y  + y - x  + x  + 10 x + 20
-            sage: print F.solve(y)
-            [
-                                  3      2
-                        - sqrt(4 x  - 4 x  - 40 x - 79) - 1
-                    y == -----------------------------------
-                                         2,
-                                 3      2
-                         sqrt(4 x  - 4 x  - 40 x - 79) - 1
-                     y == ---------------------------------
-                                         2
-            ]
-
-        You can also solve for x in terms of y, but the result is horrendous.
-        Continuing with the above example, we can explicitly find points
-        over random fields by substituting in values for x:
-        
-            sage: v = F.solve(y)[0].rhs()   
-            sage: print v
-                                            3      2
-                                  - sqrt(4 x  - 4 x  - 40 x - 79) - 1
-                                  -----------------------------------
-                                                   2
-            sage: v(3)
-            (-sqrt(127)*I - 1)/2
-            sage: v(7)
-            (-sqrt(817) - 1)/2
-            sage: v(-7)
-            (-sqrt(1367)*I - 1)/2
-            sage: v(sqrt(2))
-            (-sqrt(-32*sqrt(2) - 87) - 1)/2
-
-        We can even do arithmetic with them, as follows:
-            sage: E2 = E.change_ring(SR); E2
-            Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Symbolic Ring
-            sage: P = E2(3, v(3))
-            sage: P
-            (3 : (-sqrt(127)*I - 1)/2 : 1)
-            sage: P + P
-            (-756/127 : (sqrt(127)*I + 1)/2 + 12507*I/(127*sqrt(127)) - 1 : 1)
-
-        We can even throw in a transcendental:
-            sage: w = E2(pi,v(pi)); w
-            (pi : (-sqrt(4*pi^3 - 4*pi^2 - 40*pi - 79) - 1)/2 : 1)
-            sage: 2*w
-            ((3*pi^2 - 2*pi - 10)^2/(4*pi^3 - 4*pi^2 - 40*pi - 79) - 2*pi + 1 : (sqrt(4*pi^3 - 4*pi^2 - 40*pi - 79) + 1)/2 - ((3*pi^2 - 2*pi - 10)*((-(3*pi^2 - 2*pi - 10)^2)/(4*pi^3 - 4*pi^2 - 40*pi - 79) + 3*pi - 1)/(sqrt(4*pi^3 - 4*pi^2 - 40*pi - 79))) - 1 : 1)
-        """
-        a = [SR(x) for x in self.a_invariants()]
-        x, y = SR.var('x, y')
-        return y**2 + a[0]*x*y + a[2]*y == x**3 + a[1]*x**2 + a[3]*x + a[4]
+        return 'EllipticCurve([%s])'%(','.join([x._magma_init_() for x in self.ainvs()]))        
         
     def __cmp__(self, other):
@@ -322,5 +244,5 @@
         return y**2 + a[0]*x*y + a[2]*y == x**3 + a[1]*x**2 + a[3]*x + a[4]
 
-    def __call__(self, *args, **kwds):
+    def __call__(self, *args):
         """
         EXAMPLES:
@@ -374,9 +296,18 @@
             sage: P+P
             (0 : 1 : 0)
+
+        We can create points that aren't really on the curve (but we
+        must use the point command):
+            sage: E = EllipticCurve('37a').change_ring(Qp(5))
+            sage: P = E.point([1,2,3],check=False)
+            sage: P
+            (1 : 2 : 3)
+            sage: P+P
+            (4*5^-2 + 3 + 4*5 + 4*5^2 + 4*5^3 + 4*5^4 + 4*5^5 + 4*5^6 + 4*5^7 + 4*5^8 + 4*5^9 + 4*5^10 + 4*5^11 + 4*5^12 + 4*5^13 + 4*5^14 + 4*5^15 + 4*5^16 + O(5^17) : 2*5^-3 + 3*5^-2 + 3 + 4*5 + 4*5^2 + 4*5^3 + 4*5^4 + 4*5^5 + 4*5^6 + 4*5^7 + 4*5^8 + 4*5^9 + 4*5^10 + 4*5^11 + 4*5^12 + 4*5^13 + 4*5^14 + 4*5^15 + O(5^16) : 1)
         """
         if len(args) == 1 and args[0] == 0:
             R = self.base_ring()
             return self.point([R(0),R(1),R(0)], check=False)
-        return plane_curve.ProjectiveCurve_generic.__call__(self, *args, **kwds)
+        return plane_curve.ProjectiveCurve_generic.__call__(self, *args)
 
     def _homset_class(self, *args, **kwds):
Index: sage/schemes/elliptic_curves/ell_modular_symbols.py
===================================================================
--- sage/schemes/elliptic_curves/ell_modular_symbols.py	(revision 3907)
+++ sage/schemes/elliptic_curves/ell_modular_symbols.py	(revision 3521)
@@ -24,5 +24,4 @@
 from sage.modular.modsym.all import ModularSymbols
 from sage.rings.arith import next_prime
-from sage.rings.infinity import unsigned_infinity as infinity
 
 def modular_symbol_space(E, sign, base_ring, bound=None):
@@ -38,7 +37,4 @@
     OUTPUT:
         a space of modular symbols
-
-    EXAMPLES:
-
     """
     _sign = int(sign)
@@ -62,31 +58,10 @@
 
 class ModularSymbol(SageObject):
-    r"""
-    A modular symbol attached to an elliptic curve, which is the map
-    from $\QQ\to \QQ$ obtained by sending $r$ to the normalized
-    symmetrized (or anti-symmetrized) integral from r to infinity.
-
-    This is as defined in Mazur-Tate-Teitelbaum.  It's possible the
-    map could be off from what you expect by -1 or +/- 2, but
-    otherwise it is definitely normalized correctly.
-
-    EXAMPLES:
-    
-    """
-    def __init__(self, E, sign, normalize=True):
+    def __init__(self, E, sign, base_ring):
         """
         INPUT:
             E -- an elliptic curve
             sign -- an integer, -1 or 1
-            normalize -- (default: True); if True, the modular symbol
-                is correctly normalized (up to possibly a factor of
-                -1 or 2).  If False, the modular symbol is almost certainly
-                not correctly normalized, i.e., all values will be a
-                fixed scalar multiple of what they should be.  But
-                the initial computation of the modular symbol is
-                much faster, though evaluation of it after computing
-                it won't be any faster. 
-
-        EXAMPLES:
+            base_ring -- a ring
         """
         _sign = int(sign)
@@ -96,28 +71,13 @@
             raise TypeError, 'sign must -1 or 1'
         self._E = E
-        self._modsym = E.modular_symbol_space(sign=_sign)
+        self._modsym = E.modular_symbol_space(sign=_sign, base_ring=base_ring)
         self._ambient_modsym = self._modsym.ambient_module()
-        if normalize:
-            P = self._modsym.integral_period_mapping()
-            e = P.matrix().transpose()[0]
-            e /= 2
-        else:
-            e = self._modsym.dual_eigenvector()
-        self._e = e
+        self._e = self._modsym.dual_eigenvector()
+        # todo -- here must rescale self._e
 
     def sign(self):
-        """
-        Return the sign of this elliptic curve modular symbol.
-
-        EXAMPLES:
-        """
-    
         return self._modsym.sign()
 
     def base_ring(self):
-        """
-        Return the base ring for this modular symbol. 
-        EXAMPLES:
-        """
         return self._modsym.base_ring()
 
@@ -125,6 +85,6 @@
         return self._E
 
-    def __call__(self, r):
-        w = self._ambient_modsym([infinity,r]).element()
+    def __call__(self, x):
+        w = self._ambient_modsym([0,x]).element()
         return (self._e).dot_product(w)
 
Index: sage/schemes/elliptic_curves/ell_padic_field.py
===================================================================
--- sage/schemes/elliptic_curves/ell_padic_field.py	(revision 3890)
+++ sage/schemes/elliptic_curves/ell_padic_field.py	(revision 3664)
@@ -160,19 +160,17 @@
     def coleman_integrals_on_basis(self, P, Q):
         """
-        Return the coleman integral of dx/y and x dx/y from P to Q.
-        
-        EXAMPLES:
-            sage: K = pAdicField(13, 7)
-            sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a
-            sage: P = E(K(14/3), K(11/2))
-            sage: res = E.coleman_integrals_on_basis(P, 2*P); res
-            (7*13^6 + O(13^7), 2 + 7*13 + 2*13^2 + 5*13^3 + 10*13^4 + 7*13^5 + 8*13^6 + O(13^7))
-
-        As the Coleman integral of dx/y is in invariant under
-        translation, it should evaluate to zero between a torsion
-        point and its multiples.
-
-            sage: res[0].valuation() >= 6
-            True
+        Return the coleman integral of dx/y and x dx/y from P to Q
+        
+        sage: K = pAdicField(13, 7)
+        sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a
+        sage: P = E(K(14/3), K(11/2))
+        sage: res = E.coleman_integrals_on_basis(P, 2*P); res
+        (7*13^6 + O(13^7), 2 + 7*13 + 2*13^2 + 5*13^3 + 10*13^4 + 7*13^5 + 8*13^6 + O(13^7))
+        
+        As the Coleman integral of dx/y is in invariant under translation, it should 
+        evaluate to zero between a torsion point and its multiples. 
+        
+        sage: res[0].valuation() >= 6
+        True
         """
         K = self.base_field()
Index: sage/schemes/elliptic_curves/ell_point.py
===================================================================
--- sage/schemes/elliptic_curves/ell_point.py	(revision 4059)
+++ sage/schemes/elliptic_curves/ell_point.py	(revision 3374)
@@ -143,5 +143,5 @@
         return self.scheme()
 
-    def __nonzero__(self):
+    def is_zero(self):
         """
         Return True if this is the zero point on the curve.
@@ -157,5 +157,5 @@
             False
         """
-        return bool(self[2])
+        return self[2] == 0
 
     def is_finite_order(self):
Index: sage/schemes/elliptic_curves/ell_rational_field.py
===================================================================
--- sage/schemes/elliptic_curves/ell_rational_field.py	(revision 4065)
+++ sage/schemes/elliptic_curves/ell_rational_field.py	(revision 3686)
@@ -546,5 +546,5 @@
             return f
 
-    def modular_symbol_space(self, sign=1, base_ring=Q, bound=None):
+    def modular_symbol_space(self, sign=1, base_ring=Q):
         r"""
         Return the space of cuspidal modular symbols associated to
@@ -556,12 +556,5 @@
 
         EXAMPLES:
-            sage: f = EllipticCurve('37b')
-            sage: f.modular_symbol_space()
-            Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(37) of weight 2 with sign 1 over Rational Field
-            sage: f.modular_symbol_space(-1)
-            Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 2 for Gamma_0(37) of weight 2 with sign -1 over Rational Field
-            sage: f.modular_symbol_space(0, bound=3)
-            Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Gamma_0(37) of weight 2 with sign 0 over Rational Field
-        
+
         NOTE: If you just want the $q$-expansion, use
         \code{self.q_expansion(prec)}.
@@ -574,9 +567,9 @@
         except KeyError:
             pass
-        M = ell_modular_symbols.modular_symbol_space(self, sign, base_ring, bound=bound)
+        M = ell_modular_symbols.modular_symbol_space(self, sign, base_ring)
         self.__modular_symbol_space[typ] = M
         return M
 
-    def modular_symbol(self, sign=1, normalize=True):
+    def modular_symbol(self, sign=1, base_ring=Q):
         r"""
         Return the modular symbol associated to this elliptic curve,
@@ -585,25 +578,15 @@
         normalized so that all values of this map take values in QQ.
 
-        If sign=1, the normalization is such that the p-adic
-        L-function associated to this modular symbol is correct.
-        I.e., the normalization is the same as for the integral period
-        mapping divided by 2.
+        NOTE: Currently there is no guarantee about how this map is
+        normalized.  This will be added. 
 
         INPUT:
             sign -- -1, or 1
             base_ring -- a ring
-            normalize -- (default: True); if True, the modular symbol
-                is correctly normalized (up to possibly a factor of
-                -1 or 2).  If False, the modular symbol is almost certainly
-                not correctly normalized, i.e., all values will be a
-                fixed scalar multiple of what they should be.  But
-                the initial computation of the modular symbol is
-                much faster, though evaluation of it after computing
-                it won't be any faster. 
-
-        EXAMPLES:
-        
-        """
-        typ = (sign, normalize)
+
+        NOTE: If you just want the $q$-expansion, use
+        \code{self.q_expansion(prec)}.
+        """
+        typ = (sign, base_ring)
         try:
             return self.__modular_symbol[typ]
@@ -612,20 +595,15 @@
         except KeyError:
             pass
-        M = ell_modular_symbols.ModularSymbol(self, sign, normalize)
+        M = ell_modular_symbols.ModularSymbol(self, sign, base_ring)
         self.__modular_symbol[typ] = M
         return M
 
-    def padic_lseries(self, p, normalize=True):
-        r"""
-        Return the $p$-adic $L$-series of self at $p$, which is an object
-        whose approx method computes approximation to the true $p$-adic
-        $L$-series to any deesired precision.
+    def padic_lseries(self, p, prec=20):
+        """
+        Return the p-adic Lseries of self at p with given p-adic precision.
         
         INPUT:
             p -- prime
-            normalize -- (default: True); if True the p-adic L-series
-            is normalized correctly (up to multiplication by -1 and
-            2); otherwise it isn't, but computation of the series is
-            quicker.
+            prec -- precision of p-adic computations
 
         EXAMPLES:
@@ -634,46 +612,7 @@
             5-adic L-series of Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
             sage: type(L)
-            <class 'sage.schemes.elliptic_curves.padic_lseries.pAdicLseriesOrdinary'>
-
-        We compute the $3$-adic $L$-series of two curves of rank $0$
-        and in each case verify the interpolation property for their
-        leading coefficient (i.e., value at 0):
-            sage: e = EllipticCurve('11a')
-            sage: ms = e.modular_symbol()
-            sage: [ms(1/11), ms(1/3), ms(0), ms(oo)]
-            [0, -3/10, 1/5, 0]
-            sage: ms(0)
-            1/5
-            sage: L = e.padic_lseries(3)
-            sage: P = L.series(5)
-            sage: P(0)
-            2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7)
-            sage: alpha = L.alpha(9); alpha
-            2 + 3^2 + 2*3^3 + 2*3^4 + 2*3^6 + 3^8 + O(3^9)
-            sage: R.<x> = QQ[]
-            sage: f = x^2 - e.ap(3)*x + 3
-            sage: f(alpha)
-            O(3^9)
-            sage: r = e.L_ratio(); r
-            1/5
-            sage: (1 - alpha^(-1))^2 * r
-            2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + 3^7 + O(3^9)
-            sage: P(0)
-            2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7)
-
-        Next consider the curve 37b:
-            sage: e = EllipticCurve('37b')
-            sage: L = e.padic_lseries(3)
-            sage: P = L.series(5)
-            sage: alpha = L.alpha(9); alpha
-            1 + 2*3 + 3^2 + 2*3^5 + 2*3^7 + 3^8 + O(3^9)
-            sage: r = e.L_ratio(); r
-            1/3
-            sage: (1 - alpha^(-1))^2 * r
-            3 + 3^2 + 2*3^4 + 2*3^5 + 2*3^6 + 3^7 + O(3^9)
-            sage: P(0)
-            3 + 3^2 + 2*3^4 + 2*3^5 + 2*3^6 + O(3^7)
-        """
-        key = (p, normalize)
+            <class 'sage.schemes.elliptic_curves.padic_lseries.pAdicLseriesOrdinary'>        
+        """
+        key = (p,prec)
         try:
             return self._padic_lseries[key]
@@ -683,14 +622,12 @@
             pass
         if self.ap(p) % p != 0:
-            Lp = padic_lseries.pAdicLseriesOrdinary(self, p,
-                                  normalize = normalize)
+            Lp = padic_lseries.pAdicLseriesOrdinary(self, p, prec)
         else:
-            Lp = padic_lseries.pAdicLseriesSupersingular(self, p, 
-                                  normalize = normalize)
+            Lp = padic_lseries.pAdicLseriesSupersingular(self, p, prec)
         self._padic_lseries[key] = Lp
         return Lp
 
     def newform(self):
-        r"""
+        """
         Same as \code{self.modular_form()}.
         """
@@ -698,6 +635,6 @@
 
     def q_eigenform(self, prec):
-        r"""
-        Synonym for \code{self.q_expansion(prec)}.
+        """
+        Synonym for self.q_expansion(prec).
         """
         return self.q_expansion(prec)
@@ -1506,29 +1443,4 @@
         return tuple(self.pari_curve().omega().python())
 
-    def period_lattice_is_rectangular(self):
-        r"""
-        Return True precisely if the period lattice of self
-        is rectangular.
-
-        EXAMPLES:
-            sage: f = EllipticCurve('11a')
-            sage: f.period_lattice()
-            (1.269209304279553421688794616754547305219492241830608667967136921230408338613, 0.6346046521397767108443973083772736526097461209153043339835684606152041693064 + 1.458816616938495229330889612903675257159243428952665161469618762450537896609*I)                                     # 32-bit
-            (1.26920930427955342168879461675454730521949224183060866796713692123040833861277772269036230592151260731164529627832128743728170032847684397649271401057075, 0.634604652139776710844397308377273652609746120915304333983568460615204169306388861345181152960756303655822648139160643718640850164238421988246357005285375 + 1.45881661693849522933088961290367525715924342895266516146961876245053789660902872639765673368315820172095257526042401249237362183079269125313009041993832*I)             # 64-bit
-            sage: f.period_lattice_is_rectangular()
-            False
-            sage: f = EllipticCurve('37b')
-            sage: f.period_lattice()
-            (1.088521592904229173504308311539594823105140504301377799086597419750048367573, 1.767610670233789475881323144497815233734289378984139837146363810096739201810*I)           # 32-bit
-             (1.08852159290422917350430831153959482310514050430137779908659741975004836757281196724615591294512604175793056433512324867543024134734839104934760089947025, 1.76761067023378947588132314449781523373428937898413983714636381009673920180953691706599273805495417094215579677634900614786897226142483706622542207437740*I)   # 64-bit
-            sage: f.period_lattice_is_rectangular()
-            True        
-
-        ALGORITHM:
-           The period lattice is rectangular precisely if the
-           discriminant of the Weierstrass equation is positive.
-        """
-        return self.discriminant() > 0
-
     def omega(self):
         """
@@ -2403,46 +2315,4 @@
             raise ValueError, "unknown algorithm '%s'%"%algorithm
     
-    def isogeny_graph(self):
-        r"""
-        Returns a graph representing the isogeny class of this elliptic curve,
-        where the vertices are isogenous curves over $\Q$ and the edges are
-        prime degree isogenies labeled by their degree.
-
-        EXAMPLES:
-            sage: LL = []
-            sage: for e in cremona_optimal_curves(range(1, 38)):
-            ...    G = e.isogeny_graph()
-            ...    already = False
-            ...    for H in LL:
-            ...        if G.is_isomorphic(H):
-            ...            already = True
-            ...            break
-            ...    if not already:
-            ...        LL.append(G)
-            ...
-            sage.: graphs_list.show_graphs(LL)
-            
-            sage: E = EllipticCurve('195a')
-            sage: G = E.isogeny_graph()
-            sage: for v in G: print v, G.obj(v)
-            ...
-            0 Elliptic Curve defined by y^2 + x*y  = x^3 - 110*x + 435 over Rational Field
-            1 Elliptic Curve defined by y^2 + x*y  = x^3 - 115*x + 392 over Rational Field
-            2 Elliptic Curve defined by y^2 + x*y  = x^3 + 210*x + 2277 over Rational Field
-            3 Elliptic Curve defined by y^2 + x*y  = x^3 - 520*x - 4225 over Rational Field
-            4 Elliptic Curve defined by y^2 + x*y  = x^3 + 605*x - 19750 over Rational Field
-            5 Elliptic Curve defined by y^2 + x*y  = x^3 - 8125*x - 282568 over Rational Field
-            6 Elliptic Curve defined by y^2 + x*y  = x^3 - 7930*x - 296725 over Rational Field
-            7 Elliptic Curve defined by y^2 + x*y  = x^3 - 130000*x - 18051943 over Rational Field
-            sage: G.plot(edge_labels=True).save('isogeny_graph.png')
-        """
-        from sage.graphs.graph import Graph
-        L, M = self.isogeny_class()
-        G = Graph(M, format='weighted_adjacency_matrix')
-        d = {}
-        for v in G.vertices():
-            d[v] = L[v]
-        G.associate(d)
-        return G
 
     ##########################################################
@@ -2454,9 +2324,4 @@
         Return True if the mod-p representation attached
         to E is reducible.
-
-        INPUT:
-            p -- a prime number
-
-        NOTE: The answer is cached. 
 
         EXAMPLES:
@@ -2475,18 +2340,8 @@
             1        
         """
-        try:
-            return self.__is_reducible[p]
-        except AttributeError:
-            self.__is_reducible = {}
-        except KeyError:
-            pass
-
-        if not arith.is_prime(p):
-            raise ValueError, 'p (=%s) must be prime'%p
         # we do is_surjective first, since this is
         # much easier than computing isogeny_class
         t, why = self.is_surjective(p)  
         if t == True:
-            self.__is_reducible[p] = False
             return False  # definitely not reducible
         isogeny_matrix = self.isogeny_class()[ 1 ]
@@ -2494,7 +2349,5 @@
         for a in v:
             if a != 0 and a % p == 0:
-                self.__is_reducible[p] = True
                 return True
-        self.__is_reducible[p] = False
         return False
 
@@ -2502,17 +2355,6 @@
         """
         Return True if the mod p represenation is irreducible.
-
-        EXAMPLES:
-            sage: e = EllipticCurve('37b')
-            sage: e.is_irreducible(2)
-            True
-            sage: e.is_irreducible(3)
-            False
-            sage: e.is_reducible(2)
-            False
-            sage: e.is_reducible(3)
-            True        
-        """
-        return not self.is_reducible(p)
+        """
+        return not self.is_reducible()
         
     def is_surjective(self, p, A=1000):
@@ -2520,7 +2362,5 @@
         Return True if the mod-p representation attached to E
         is surjective, False if it is not, or None if we were
-        unable to determine whether it is or not.
-
-        NOTE: The answer is cached. 
+        unable to determine whether it is or not.  
 
         INPUT:
@@ -2534,10 +2374,4 @@
 
         EXAMPLES:
-            sage: e = EllipticCurve('37b')
-            sage: e.is_surjective(2)
-            (True, None)
-            sage: e.is_surjective(3)
-            (False, '3-torsion')
-            
 
         REMARKS:
@@ -2556,18 +2390,5 @@
         if not arith.is_prime(p):
             raise TypeError, "p (=%s) must be prime."%p
-        A = int(A)
-        key = (p, A)
-        try:
-            return self.__is_surjective[key]
-        except KeyError:
-            pass
-        except AttributeError:
-            self.__is_surjective = {}
-
-        ans = self._is_surjective(p, A)
-        self.__is_surjective[key] = ans
-        return ans
-
-    def _is_surjective(self, p, A):
+
         T = self.torsion_subgroup().order()
         if T % p == 0:
Index: sage/schemes/elliptic_curves/monsky_washnitzer.py
===================================================================
--- sage/schemes/elliptic_curves/monsky_washnitzer.py	(revision 4065)
+++ sage/schemes/elliptic_curves/monsky_washnitzer.py	(revision 3665)
@@ -46,7 +46,6 @@
 from sage.matrix.matrix_space import MatrixSpace
 
-from sage.rings.arith import binomial, integer_ceil as ceil, integer_floor as floor
-from math import floor
-from sage.misc.functional import log, sqrt
+from sage.rings.arith import binomial, floor
+from sage.misc.functional import log, ceil, sqrt
 
 
Index: sage/schemes/elliptic_curves/padic_lseries.py
===================================================================
--- sage/schemes/elliptic_curves/padic_lseries.py	(revision 3913)
+++ sage/schemes/elliptic_curves/padic_lseries.py	(revision 3451)
@@ -23,122 +23,29 @@
 
 from sage.rings.integer_ring import ZZ
-from sage.rings.rational_field import QQ
 from sage.rings.padics.qp import Qp
-from sage.rings.infinity import infinity
 
 from sage.rings.integer import Integer
-from sage.rings.arith import valuation, binomial
 
 from sage.structure.sage_object import SageObject
 
-from sage.misc.all import verbose
-
 class pAdicLseries(SageObject):
-    """
-    The p-adic L-series of an elliptic curve.
-
-    EXAMPLES:
-    A superingular example:
-        sage: e = EllipticCurve('37a')
-        sage: L = e.padic_lseries(3); L
-        3-adic L-series of Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
-        sage: L.series(2)
-        WARNING: supersingular prime -- answer is *not* to as high of precision as claimed.
-        ((3^-1 + O(3^3))*alpha + 2*3^-1 + O(3^3))*T + ((3^-1 + O(3^3))*alpha + 2*3^-1 + O(3^3))*T^2 + O(T^3)
-        
-    An ordinary example:
-        sage: e = EllipticCurve('389a')
-        sage: L = e.padic_lseries(5)
-        sage: L.series(0)
-        Traceback (most recent call last):
-        ...
-        ValueError: n (=0) must be a positive integer
-        sage: L.series(1)
-        O(T^1)
-        sage: L.series(2)
-        (4 + O(5))*T^2 + (2 + O(5))*T^3 + (3 + O(5))*T^4 + O(T^5)
-        sage: L.series(3)
-        (4 + 4*5 + O(5^2))*T^2 + (2 + 4*5 + O(5^2))*T^3 + (3 + O(5^2))*T^4 + (1 + O(5))*T^5 + (3*5 + O(5^2))*T^6 + (4 + 5 + O(5^2))*T^7 + (2 + 5 + O(5^2))*T^8 + (5 + O(5^2))*T^11 + (2 + O(5^2))*T^12 + (1 + 3*5 + O(5^2))*T^13 + (4 + 4*5 + O(5^2))*T^14 + (3 + O(5))*T^15 + (3*5 + O(5^2))*T^16 + (3*5 + O(5^2))*T^17 + (1 + 4*5 + O(5^2))*T^19 + (3 + O(5))*T^20 + (4 + 3*5 + O(5^2))*T^21 + (2 + O(5^2))*T^22 + (2 + O(5^2))*T^23 + (2 + O(5^2))*T^24 + O(T^25)
-
-    A prime p such that E[p] is reducible:
-        sage: L = EllipticCurve('11a').padic_lseries(5)
-        sage: L.series(1)
-        5 + 4*5^2 + O(5^3) + O(T)
-        sage: L.series(2)
-        5 + 4*5^2 + 4*5^3 + O(5^4) + O(T^5)
-        sage: L.series(3)
-        5 + 4*5^2 + 4*5^3 + O(5^5) + (4*5 + O(5^2))*T + (5 + O(5^2))*T^2 + (4*5 + O(5^2))*T^3 + (3*5 + O(5^2))*T^4 + (3*5 + O(5^2))*T^6 + (4*5 + O(5^2))*T^8 + (5 + O(5^2))*T^9 + (5 + O(5^2))*T^11 + (3*5 + O(5^2))*T^13 + (3*5 + O(5^2))*T^14 + (3*5 + O(5^2))*T^16 + (4*5 + O(5^2))*T^18 + (2*5 + O(5^2))*T^21 + (3*5 + O(5^2))*T^22 + (2*5 + O(5^2))*T^23 + (2*5 + O(5^2))*T^24 + O(T^25)
-        
-    """
-    def __init__(self, E, p, normalize):
-        """
-        INPUT:
-            E -- an elliptic curve
-            p -- a prime of good reduction
-            normalize -- (bool, default: True); whether or not to correctly
-                 normalize the L-series, up to a power of -1 and 2.
-                 If False computations may be faster.
-        """
+    def __init__(self, E, p, prec):
         self._E = E
         self._p = ZZ(p)
-        self._normalize = normalize
         if not self._p.is_prime():
             raise ValueError, "p (=%s) must be a prime"%p
         #if E.conductor() % self._p == 0:
         #    raise NotImplementedError, "p (=%s) must be a prime of good reduction"%p
-        self._modular_symbol = E.modular_symbol(sign=1, normalize=normalize)
-
-    def elliptic_curve(self):
-        """
-        Return the elliptic curve to which this p-adic L-series is associated.
-        
-        EXAMPLES:
-            sage: L = EllipticCurve('11a').padic_lseries(5)
-            sage: L.elliptic_curve()
-            Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
-        """
-        return self._E
-
-    def prime(self):
-        """
-        EXAMPLES:
-            sage: L = EllipticCurve('11a').padic_lseries(5)
-            sage: L.prime()
-            5
-        """
-        return self._p
+        self._prec = prec
+        self._modular_symbol = E.modular_symbol()
+        self._Qp = Qp(p, self._prec, print_mode='series')
 
     def _repr_(self):
-        """
-        Return print representation.
+        return "%s-adic L-series of %s"%(self._p, self._E)
 
-            sage: e = EllipticCurve('37a')
-            sage: e.padic_lseries(3)
-            3-adic L-series of Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
-            sage: e.padic_lseries(3,normalize=False)
-            3-adic L-series of Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field (not normalized)
-            sage: L = e.padic_lseries(3,normalize=False)
-            sage: L.rename('(factor)*L_3(T)')
-            sage: L
-            (factor)*L_3(T)
-        """
-        s = "%s-adic L-series of %s"%(self._p, self._E)
-        if not self._normalize:
-            s += ' (not normalized)'
-        return s
+    def modular_symbol(self, x):
+        return self._modular_symbol(x)
 
-    def modular_symbol(self, r):
-        """
-        Return the modular symbol used to compute this p-adic
-        L-series evaluated at r.
-
-        EXAMPLES:
-            sage: L = EllipticCurve('11a').padic_lseries(5)
-            sage: [L.modular_symbol(r) for r in [0,1/5,oo,1/11]]
-            [1/5, 6/5, 0, 0]        
-        """
-        return self._modular_symbol(r)
-
-    def measure(self, a, n, prec):
+    def measure(self, a, n):
         r"""
         Return the measure on $\ZZ_p^*$ defined by
@@ -149,17 +56,11 @@
         that is used to define this $p$-adic $L$-function.
 
-        INPUT:
-            a -- an integer
-            n -- a non-negative integer
-            prec -- an integer
-
-        EXAMPLES:
             sage: E = EllipticCurve('37a')
-            sage: L = E.padic_lseries(5)
-            sage: L.measure(1,2, prec=9)
-            1 + 4*5 + 2*5^2 + 4*5^3 + 3*5^4 + 5^5 + 4*5^6 + 4*5^7 + 4*5^8 + O(5^9)
+            sage: L = E.padic_lseries(5, prec=9)
+            sage: L.measure(1,2)
+            2 + 3*5 + 4*5^3 + 2*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 4*5^8 + O(5^9)        
         """
         p = self._p
-        alpha = self.alpha(prec)
+        alpha = self.alpha()
         z = 1/(alpha**n)
         w = p**(n-1)
@@ -167,185 +68,59 @@
         return z * f(a/(p*w)) - (z/alpha) * f(a/w)
         
-    def alpha(self, prec):
+    def alpha(self):
         r"""
-        Return a p-adic root $\alpha$ of the polynomial $x^2 - a_p x
-        + p$ with $\ord_p(\alpha) < 1$.  In the ordinary case this is
-        just the unit root.
-
-        INPUT:
-            prec -- positive integer, the p-adic precision of the root.
+        Return the p-adic root $\alpha$ of the polynomial $x^2 - a_p x
+        + p$ with $\ord_p(\alpha) < 1$.
 
         EXAMPLES:
-        Consider the elliptic curve 37a:
             sage: E = EllipticCurve('37a')
-
-        An ordinary prime:
-            sage: L = E.padic_lseries(5)
-            sage: alpha = L.alpha(10); alpha
-            3 + 2*5 + 4*5^2 + 2*5^3 + 5^4 + 4*5^5 + 2*5^7 + 5^8 + 5^9 + O(5^10)
-            sage: alpha^2 - E.ap(5)*alpha + 5
-            O(5^10)
-
-        A supersingular prime.
-            sage: L = E.padic_lseries(3)
-            sage: alpha = L.alpha(10); alpha
-            (1 + O(3^10))*alpha
-            sage: alpha^2 - E.ap(3)*alpha + 3
-            0
-
-        A reducible prime:
-            sage: L = EllipticCurve('11a').padic_lseries(5)
-            sage: L.alpha(5)
-            1 + 4*5 + 3*5^2 + 2*5^3 + 4*5^4 + O(5^5)
+            sage: L = E.padic_lseries(5, prec=10)
+            sage: L.alpha()
+            3 + 2*5 + 4*5^2 + 2*5^3 + 5^4 + 4*5^5 + 2*5^7 + 5^8 + 5^9 + O(5^10)        
         """
         try:
-            return self._alpha[prec]
+            return self._alpha
         except AttributeError:
-            self._alpha = {}
-        except KeyError:
             pass
         E = self._E
         p = self._p
         a_p = E.ap(p)
-        K = Qp(p, prec, print_mode='series')
 
         R = ZZ['x']
         f = R([p, -a_p, 1])
         if E.is_ordinary(p):
-            G = f.factor_padic(p, prec+5)
+            G = f.factor_padic(p, self._prec)
             for pr, e in G:
                 a = -pr[0]
                 if a.valuation() < 1:
-                    self._alpha[prec] = K(a)
-                    return K(a)
+                    self._alpha = self._Qp(a)
+                    return self._Qp(a)
             raise ValueError, "bug in p-adic L-function alpha"
         else: # supersingular case
-            f = f.change_ring(Qp(p, prec, print_mode='series'))
+            f = f.change_ring(Qp(p, self._prec, print_mode='series'))
             a = f.root_field('alpha', check_irreducible=False).gen()
-            self._alpha[prec] = a
+            self._alpha = a
             return a
 
-    def order_of_vanishing(self, proof=True):
+    def approx(self, n):
         """
-        Return the order of vanishing of this p-adic L-series.
+        Return the n-th approximation to the p-adic L-series as a
+        power series in T.
 
-        The output of this function is provably correct, due to a
-        theorem of Kato.  This function will terminate if and only if
-        the Mazur-Tate-Teitelbaum analogue of the BSD conjecture about
-        the rank of the curve is true and the subgroup of elements of
-        p-power order in the Shafarevich-Tate group of this curve is
-        finite.  I.e., if this function terminates (with no errors!),
-        then you may conclude that the p-adic BSD rank conjecture is
-        true and that the p-part of Sha is finite.
-
-        NOTE: currently p must be a prime of good ordinary reduction.
+        INPUT:
+            n -- an integer
 
         EXAMPLES:
-            sage: L = EllipticCurve('11a').padic_lseries(3)
-            sage: L.order_of_vanishing()
-            0
-            sage: L = EllipticCurve('11a').padic_lseries(5)                        
-            sage: L.order_of_vanishing()
-            0        
-            sage: L = EllipticCurve('37a').padic_lseries(5)
-            sage: L.order_of_vanishing()
-            1
-            sage: L = EllipticCurve('43a').padic_lseries(3)
-            sage: L.order_of_vanishing()
-            1
-            sage: L = EllipticCurve('37b').padic_lseries(3)
-            sage: L.order_of_vanishing()
-            0
-
-        We verify that Sha(E)(p) is finite for p=3,5,7 for the
-        first curve of rank 2:
-            sage: e = EllipticCurve('389a')
-            sage: for p in primes(3,10):
-            ...    print p, e.padic_lseries(p).order_of_vanishing()
-            3 2
-            5 2
-            7 2            
-        """
-        try:
-            return self.__ord
-        except AttributeError:
-            pass
-        
-        if not self.is_ordinary():
-            raise NotImplementedError
-        E = self.elliptic_curve()
-        if not E.is_good(self.prime()):
-            raise ValueError, "prime must be of good reduction"
-        r = E.rank()
-        n = 1
-        while True:
-            f = self.series(n)
-            v = f.valuation()
-            if v < r:
-                raise RuntimeError, "while computing p-adic order of vanishing, got a contradiction: the curve is %s, the curve has rank %s, but the p-adic L-series vanishes to order <= %s"%(E, r, v)
-            if v == r:
-                self.__ord = v
-                return v
-            n += 1
-
-
-    def _c_bounds(self, n):
-        raise NotImplementedError
-
-    def _prec_bounds(self, n):
-        raise NotImplementedError
-
-    def teichmuller(self, prec):
-        r"""
-        Return Teichmuller lifts to the given precision.
-        
-        INPUT:
-            prec -- a positive integer.
-            
-        OUTPUT:
-            the cached Teichmuller lifts 
-
-        EXAMPLES:
-            sage: L = EllipticCurve('11a').padic_lseries(7)
-            sage: L.teichmuller(1)
-            [0, 1, 2, 3, 4, 5, 6]
-            sage: L.teichmuller(2)
-            [0, 1, 30, 31, 18, 19, 48]
-        """
-        p = self._p
-        K = Qp(p, prec, print_mode='series')        
-        return [Integer(0)] + \
-               [a.residue(prec).lift() for a in K.teichmuller_system()]
-
-    def _e_bounds(self, n):
-        p = self._p
-        T = (ZZ['T']).gen()
-        w = (1+T)**(p**n) - 1
-        return [infinity] + [valuation(w[j],p) for j in range(1,w.degree()+1)]
-        
-
-class pAdicLseriesOrdinary(pAdicLseries):
-    def series(self, n):
-        """
-        Return the n-th approximation to the p-adic L-series as a
-        power series in T.  Each coefficient is a p-adic number whose
-        precision is provably correct (as long as p is a prime of
-        ordinary reduction).
-
-        INPUT:
-            n -- a positive integer
-
-        EXAMPLES:
-        We compute some $p$-adic $L$-functions associated to the elliptic
-        curve 11a.
-        
+        We compute some $p$-adic $L$-functions associated to the elliptic curve 11a.
             sage: E = EllipticCurve('11a')
             sage: p = 3
             sage: E.is_ordinary(p)
             True
-            sage: L = E.padic_lseries(p)
-            sage: L.series(3)
-            2 + 3 + 3^2 + 2*3^3 + O(3^5) + (1 + 3 + O(3^2))*T + (1 + 2*3 + O(3^2))*T^2 + (2*3 + O(3^2))*T^4 + (2 + O(3^2))*T^5 + (1 + O(3))*T^6 + (2 + O(3^2))*T^7 + (2 + O(3^2))*T^8 + O(T^9)
+            sage: L = E.padic_lseries(p, prec=10)
 
+            #sage: L.approx(4)
+            #1 + 2*3 + 3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 3^6 + 3^8 + 3^9 + O(3^10) + (2 + 3^3 + 3^5 + 2*3^7 + 3^9 + O(3^10))*T + (2 + 2*3 + 2*3^2 + 3^3 + 2*3^4 + 2*3^5 + 2*3^7 + 3^8 + O(3^10))*T^2 + (2*3 + 3^2 + 3^5 + 2*3^6 + 3^8 + 2*3^9 + O(3^10))*T^3 + (3 + 2*3^2 + 3^5 + 2*3^6 + 2*3^7 + 3^8 + O(3^10))*T^4 + O(T^5)
+            #sage: L.approx(5)
+            #1 + 2*3 + 3^2 + 2*3^4 + 3^5 + 2*3^6 + O(3^10) + (2 + 3^5 + 3^6 + 2*3^7 + 3^9 + O(3^10))*T + (2 + 2*3 + 2*3^3 + 2*3^4 + 2*3^6 + 3^7 + 3^9 + O(3^10))*T^2 + (2*3 + 2*3^2 + 2*3^3 + 2*3^5 + 3^6 + 2*3^8 + 2*3^9 + O(3^10))*T^3 + (3 + 2*3^2 + 2*3^5 + 2*3^6 + 3^8 + 2*3^9 + O(3^10))*T^4 + (1 + 3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^6 + 3^7 + 3^8 + O(3^10))*T^5 + O(T^6)
 
         Another example at a prime of bad reduction, where the
@@ -357,7 +132,8 @@
             sage: E.is_ordinary(p)
             True
-            sage: L = E.padic_lseries(p)
-            sage: L.series(2)
-            (10 + O(11))*T + (6 + O(11))*T^2 + (2 + O(11))*T^3 + (5 + O(11))*T^4 + (4 + O(11))*T^5 + (1 + O(11))*T^6 + (5 + O(11))*T^8 + (6 + O(11))*T^9 + (5 + O(11))*T^10 + O(T^11)
+            sage: L = E.padic_lseries(p, prec=10)
+
+            #sage: L.approx(2)
+            #10*11^2 + 7*11^3 + 9*11^5 + 6*11^8 + 10*11^9 + O(11^10) + (6 + 8*11 + 9*11^2 + 11^3 + 11^4 + 5*11^5 + 5*11^6 + 5*11^7 + 4*11^8 + 3*11^9 + O(11^10))*T + (8 + 9*11 + 3*11^2 + 7*11^3 + 9*11^4 + 8*11^6 + 4*11^7 + 6*11^8 + 10*11^9 + O(11^10))*T^2 + O(T^3)
             
         We compute a $p$-adic $L$-function that vanishes to order $2$.
@@ -366,171 +142,58 @@
             sage: E.is_ordinary(p)
             True
-            sage: L = E.padic_lseries(p)
-            sage: L.series(1)
-            O(T^1)
-            sage: L.series(2)
-            (2 + O(3))*T^2 + O(T^3)
-            sage: L.series(3)
-            (2 + 2*3 + O(3^2))*T^2 + (2 + O(3))*T^3 + (1 + 3 + O(3^2))*T^4 + (1 + O(3^2))*T^5 + (2 + O(3))*T^6 + (1 + 3 + O(3^2))*T^7 + (1 + 3 + O(3^2))*T^8 + O(T^9)
+            sage: L = E.padic_lseries(p,prec=10)
+
+            #sage: L.approx(1)
+            #0
+            #sage: L.approx(2)
+            #(3 + 3^2 + 2*3^3 + 3^4 + 3^5 + 2*3^7 + 2*3^8 + 2*3^9 + O(3^10))*T + (2 + 2*3 + 3^2 + 3^5 + 3^6 + 2*3^7 + 2*3^8 + O(3^10))*T^2 + O(T^3)
+            #sage: L.approx(3)
+            #(2*3^2 + 3^5 + 3^6 + 2*3^7 + 2*3^8 + O(3^10))*T + (2 + 2*3 + 2*3^4 + 2*3^5 + 3^6 + 3^7 + 2*3^8 + O(3^10))*T^2 + (2 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 3^5 + O(3^10))*T^3 + O(T^4)
+            #sage: L.approx(4)
+            #(2*3^3 + 3^6 + 3^7 + 2*3^8 + 2*3^9 + O(3^10))*T + (2 + 2*3 + 2*3^2 + 3^3 + 3^4 + 2*3^5 + 2*3^6 + 2*3^7 + O(3^10))*T^2 + (2 + 2*3^2 + 3^6 + 3^8 + O(3^10))*T^3 + (1 + 2*3 + 3^3 + 2*3^4 + 2*3^5 + 3^7 + 3^8 + O(3^10))*T^4 + O(T^5)
+
         """
-        n = ZZ(n)
-        if n < 1:
-            raise ValueError, "n (=%s) must be a positive integer"%n
-        
         try:
-            return self.__series[n]
+            return self.__approx[n]
         except AttributeError:
-            self.__series = {}
+            self.__approx = {}
         except KeyError:
             pass
         
-        bounds = self._prec_bounds(n)
-        prec = max(bounds[1:]) + 5
-
         p = self._p
-
-        K = QQ
-        gamma = K(1 + p)
-        R = K[['T']]
-        T = R(R.gen(), p**(n-1))
+        gamma = 1 + p
+        R = self._Qp[['T']]
+        T = R(R.gen(), n+1)
         L = R(0)
         one_plus_T_factor = R(1)
         gamma_power = 1
-        teich = self.teichmuller(prec)
+        teich = self.teichmuller(n)
         for j in range(p**(n-1)):
-            s = K(0)
+            s = 0
             for a in range(1,p):
                 b = teich[a] * gamma_power
-                s += self.measure(b, n, prec).lift()
+                s += self.measure(b, n)
             L += s * one_plus_T_factor
             one_plus_T_factor *= 1+T
             gamma_power *= gamma
-
-        # Now create series but with each coefficient truncated
-        # so it is proven correct:
-        K = Qp(p, prec, print_mode='series')
-        R = K[['T']]
-        L = R(L)
-        aj = L.list()
-        if len(aj) > 0:
-            aj = [aj[0].add_bigoh(prec-2)] + [aj[j].add_bigoh(bounds[j]) for j in range(1,len(aj))]
-        L = R(aj, p**(n-1))
-        self.__series[n] = L
+        self.__approx[n] = L
         return L
 
-    def is_ordinary(self):
+    def teichmuller(self, n):
         """
-        EXAMPLES:
-            sage: L = EllipticCurve('11a').padic_lseries(5)            
-            sage: L.is_ordinary()
-            True
+        INPUT:
+            n -- a positive integer.
+            
+        OUTPUT:
+            the Teichmuller lifts to precision p^n as integers. 
         """
-        return True
-
-    def is_supersingular(self):
-        """
-        EXAMPLES:
-            sage: L = EllipticCurve('11a').padic_lseries(5)            
-            sage: L.is_supersingular()
-            False
-        """
-        return False
-
-    def _c_bound(self):
-        try:
-            return self.__c_bound
-        except AttributeError:
-            pass
-        E = self._E
-        p = self._p
-        if E.is_irreducible(p):
-            ans = 0
-        else:
-            m = E.modular_symbol_space(sign=1)
-            b = m.boundary_map().codomain()
-            C = b._known_cusps()  # all known, since computed the boundary map
-            ans = max([valuation(self.modular_symbol(a).denominator(), p) for a in C], [0])
-            if ans > 0:
-                ans = 0
-        self.__c_bound = ans
-        return ans
-                
-    def _prec_bounds(self, n):
-        p = self._p
-        e = self._e_bounds(n-1)
-        c = self._c_bound()
-        return [e[j] - c for j in range(len(e))]
+        K = self._Qp
+        return [Integer(0)] + \
+               [a.residue(n).lift() for a in K.teichmuller_system()]
 
 
+class pAdicLseriesOrdinary(pAdicLseries):
+    pass
+
 class pAdicLseriesSupersingular(pAdicLseries):
-    def series(self, n):
-        """
-        Return the n-th approximation to the p-adic L-series as a
-        power series in T.  Each coefficient is a p-adic number whose
-        precision is provably correct (as long as p is a prime of
-        ordinary reduction).
-
-        INPUT:
-            n -- a positive integer
-
-        EXAMPLES:
-            sage: L = EllipticCurve('37a').padic_lseries(3)
-            sage: L.series(2)
-            WARNING: supersingular prime -- answer is *not* to as high of precision as claimed.
-            ((3^-1 + O(3^3))*alpha + 2*3^-1 + O(3^3))*T + ((3^-1 + O(3^3))*alpha + 2*3^-1 + O(3^3))*T^2 + O(T^3)
-            sage: L.alpha(2).parent()
-            Univariate Quotient Polynomial Ring in alpha over 3-adic Field with capped relative precision 2 with modulus (1 + O(3^2))*x^2 + (3 + O(3^3))*x + 3 + O(3^3)
-        """
-        n = ZZ(n)
-        if n < 1:
-            raise ValueError, "n (=%s) must be a positive integer"%n
-        
-        try:
-            return self.__series[n]
-        except AttributeError:
-            self.__series = {}
-        except KeyError:
-            pass
-        
-        bounds = self._prec_bounds(n)
-        prec = max(bounds[1:]) + 5
-
-        p = self._p
-
-        alpha = self.alpha(prec)
-        K = alpha.parent()
-        gamma = 1 + p
-        R = K[['T']]
-        T = R(R.gen(), p**(n-1))
-        L = R(0)
-        one_plus_T_factor = R(1)
-        gamma_power = 1
-        teich = self.teichmuller(prec)
-        for j in range(p**(n-1)):
-            s = K(0)
-            for a in range(1,p):
-                b = teich[a] * gamma_power
-                s += self.measure(b, n, prec)
-            L += s * one_plus_T_factor
-            one_plus_T_factor *= 1+T
-            gamma_power *= gamma
-
-        # To fix this, just need to use p-adic extension rings, which
-        # David Roe has probably not quite finished yet. 
-        print 'WARNING: supersingular prime -- answer is *not* to as high of precision as claimed.'
-        self.__series[n] = L
-        return L
-
-    def is_ordinary(self):
-        return False
-
-    def is_supersingular(self):
-        return True
-
-    def _prec_bounds(self, n):
-        p = self._p
-        e = self._e_bounds(n-1)
-        c = ZZ(n+2)/2
-        return [infinity] + [(e[j] - c).floor() for j in range(1,len(e))]
-
-
+    pass
Index: sage/schemes/generic/algebraic_scheme.py
===================================================================
--- sage/schemes/generic/algebraic_scheme.py	(revision 4058)
+++ sage/schemes/generic/algebraic_scheme.py	(revision 4068)
@@ -141,5 +141,5 @@
         
     def _error_bad_coords(self, v):
-        raise TypeError, "coordinates %s do not define a point on %s"%(v,self)
+        raise TypeError, "Coordinates %s do not define a point on %s"%(v,self)
 
     def _check_satisfies_equations(self, v):
@@ -155,35 +155,16 @@
                 self._error_bad_coords(v)
 
-    def rational_points(self, F=None, B=0):
+    def rational_points(self, F=None, bound=0):
         """
         Return the set of rational points over its base ring.
-
-        EXAMPLES:
-            sage: E = EllipticCurve('37a')
-            sage: Etilde = E.base_extend(GF(3))
-            sage: Etilde.rational_points()
-            [(0 : 0 : 1),
-             (0 : 0 : 1),
-             (1 : 0 : 1),
-             (2 : 0 : 1),
-             (0 : 0 : 1),
-             (1 : 0 : 1),
-             (2 : 0 : 1),
-             (0 : 2 : 1),
-             (1 : 2 : 1),
-             (2 : 2 : 1),
-             (0 : 1 : 0),
-             (0 : 1 : 0)]
         """
         if F is None:
             F = self.base_ring()
 
-        if B == 0:
+        if bound == 0:
             if is_RationalField(F):
-                raise TypeError, \
-                      "A positive bound B (= %s) must be specified."%B
+                raise TypeError, "A positive bound (= %s) must be specified."%bound
             if not is_FiniteField(F):
-                raise TypeError, \
-                      "Argument F (= %s) must be a finite field."%F
+                raise TypeError, "Argument F (= %s) must be a finite field."%F
         pts = []
         polys = self.__X.defining_polynomials()
@@ -234,5 +215,5 @@
 
     def _error_bad_coords(self, v):
-        raise TypeError, "coordinates %s do not define a point on %s"%(list(v),self)
+        raise TypeError, "coordinates %s do not define a point on %s"%(v,self)
 
     def _check_satisfies_equations(self, v):
@@ -290,6 +271,6 @@
         We define what is clearly a union of four hypersurfaces in
         $\P^4_{\Q}$ then find the irreducible components.
-            sage: P.<x,y,z,w,v> = ProjectiveSpace(4,QQ)
-            sage: V = P.subscheme( (x^2 - y^2 - z^2)*(w^5 -  2*v^2*z^3)* w * (v^3 - x^2*z) )
+            sage: PP.<x,y,z,w,v> = ProjectiveSpace(4,QQ)
+            sage: V = PP.subscheme( (x^2 - y^2 - z^2)*(w^5 -  2*v^2*z^3)* w * (v^3 - x^2*z) )
             sage: V.irreducible_components()
             [
@@ -431,13 +412,56 @@
             self.defining_ideal(), self.defining_ideal() + other.defining_ideal())
 
-    def rational_points(self, F=None, B=0):
+    def rational_points(self, F=None, bound=0):
+        """
+        EXAMPLES:
+
+	One can enumerate points up to a given bound on a projective scheme 
+        over the rationals.
+
+            sage: E = EllipticCurve('37a')
+            sage: E.rational_points(bound=8)
+            [(0 : 0 : 1),
+             (1 : 0 : 1),
+             (-1 : 0 : 1),
+             (0 : -1 : 1),
+             (1 : -1 : 1),
+             (-1 : -1 : 1),
+             (2 : 2 : 1),
+             (2 : -3 : 1),
+             (1/4 : -3/8 : 1),
+             (1/4 : -5/8 : 1),
+             (0 : 1 : 0)]
+
+	For a small finite field, the complete set of points can be enumerated.
+
+            sage: Etilde = E.base_extend(GF(3))
+            sage: Etilde.rational_points()
+	    [(0 : 0 : 1), (1 : 0 : 1), (2 : 0 : 1), (0 : 2 : 1), (1 : 2 : 1), (2 : 2 : 1), (0 : 1 : 0)]
+
+	The class of hyperelliptic curves does not (yet) support desingularization 
+        of the places at infinity into two points.     
+
+	     sage: FF = FiniteField(7)
+	     sage: P.<x> = PolynomialRing(FiniteField(7))
+	     sage: C = HyperellipticCurve(x^8+x+1)
+	     sage: C.rational_points()
+             [(2 : 0 : 1), (4 : 0 : 1), (0 : 1 : 1), (6 : 1 : 1), (0 : 6 : 1), (6 : 6 : 1), (0 : 1 : 0)]
+
+        TODO: 
+
+	1. The above algorithms enumerate all projective points and test whethr they 
+        lie on the scheme; Implement a more naive sieve at least for covers of \P^1. 
+
+        2. Implement Stoll's model in weighted projective space to resolve singularities 
+        and find two points (1 : 1 : 0) and (-1 : 1 : 0) at infinity.
+        """
         if F == None:
             F = self.base_ring()
         X = self(F)
         if is_RationalField(F) or F == ZZ:
-            if not B > 0:
-                raise TypeError, "A positive bound B (= %s) must be specified."%B
+            if not bound > 0:
+                raise TypeError, "A positive bound (= %s) must be specified."%bound
             try:
-                return X.points(B)
+                return X.points(bound)
             except TypeError:
                 raise TypeError, "Unable to enumerate points over %s."%F
Index: sage/schemes/generic/homset.py
===================================================================
--- sage/schemes/generic/homset.py	(revision 3482)
+++ sage/schemes/generic/homset.py	(revision 4068)
@@ -4,4 +4,5 @@
 
 import sage.rings.integer_ring
+from sage.rings.arith import gcd
 
 # Some naive point enumeration routines for default.
@@ -9,12 +10,11 @@
 
 def enum_projective_rational_field(X,B):
-    n = X.codomain().ngens()
-    R = [ k-B for k in range(2*B+1) ]
+    n = X.codomain().ambient_space().ngens()
     Q = [ k+1 for k in range(B) ]
+    R = [ 0 ] + [ s*k for k in Q for s in [1,-1] ]
     pts = []
     i = int(n-1)
     while not i < 0:
         P = [ 0 for _ in range(n) ]; P[i] = 1
-        m = Z(0)
         try:
             pts.append(X(P))
@@ -22,13 +22,13 @@
             pass
         iters = [ iter(R) for _ in range(i) ]
+        [ iters[j].next() for j in range(i) ]
         j = 0
         while j < i:
             try:
-                aj = Z(iters[j].next())
-                m = m.gcd(aj)
+                aj = ZZ(iters[j].next())
                 P[j] = aj
                 for ai in Q:
                     P[i] = ai
-                    if m.gcd(ai) == 1:
+                    if gcd(P) == 1:
                         try:
                             pts.append(X(P))
@@ -36,9 +36,8 @@
                             pass
                 j = 0
-                m = Z(0)
             except StopIteration:
                 iters[j] = iter(R)  # reset
-                iters[j].next() # put at zero
                 P[j] = 0
+                P[j] = iters[j].next() # reset P[j] to 0 and increment
                 j += 1
         i -= 1
@@ -46,13 +45,13 @@
 
 def enum_affine_rational_field(X,B):
-    n = X.codomain().ngens()
-    R = [ k-B for k in range(2*B+1) ]
-    if X.value_ring() is Z:
+    n = X.codomain().ambient_space().ngens()
+    if X.value_ring() is ZZ:
         Q = [ 1 ]
     else: # rational field
         Q = [ k+1 for k in range(B) ]
+    R = [ 0 ] + [ s*k for k in range(1,B+1) for s in [1,-1] ]
     pts = []
     P = [ 0 for _ in range(n) ]
-    m = Z(0)
+    m = ZZ(0)
     try:
         pts.append(X(P))
@@ -60,8 +59,9 @@
         pass
     iters = [ iter(R) for _ in range(n) ]
+    [ iters[j].next() for j in range(n) ]
     i = 0
     while i < n:
         try:
-            a = Z(iters[i].next())
+            a = ZZ(iters[i].next())
             m = m.gcd(a)
             P[i] = a
@@ -73,14 +73,13 @@
                         pass
             i = 0
-            m = Z(0)
+            m = ZZ(0)
         except StopIteration:
-            iters[i] = iter(R)  # reset
-            iters[i].next() # put at zero
-            P[i] = 0
+            iters[i] = iter(R) # reset
+	    P[i] = iters[i].next() # reset P[i] to 0 and increment
             i += 1
     return pts
 
 def enum_projective_finite_field(X):
-    n = X.codomain().ngens()
+    n = X.codomain().ambient_space().ngens()
     R = X.value_ring()
     pts = []
@@ -92,5 +91,7 @@
         except:
             pass
+	# define some iterators and increment them:
         iters = [ iter(R) for _ in range(i) ]
+        [ iters[j].next() for j in range(i) ]
         j = 0
         while j < i:
@@ -102,9 +103,7 @@
                     pass
                 j = 0
-                m = sage.rings.integer_ring.ZZ(0)
             except StopIteration:
-                iters[j] = iter(R)  # reset
-                iters[j].next() # put at zero
-                P[j] = 0
+                iters[j] = iter(R) # reset iterator at j
+                P[j] = iters[j].next() # reset P[j] to 0 and increment
                 j += 1
         i -= 1
@@ -112,5 +111,5 @@
 
 def enum_affine_finite_field(X):
-    n = X.codomain().ngens()
+    n = X.codomain().ambient_space().ngens()
     R = X.value_ring()
     pts = []
Index: sage/schemes/generic/morphism.py
===================================================================
--- sage/schemes/generic/morphism.py	(revision 4065)
+++ sage/schemes/generic/morphism.py	(revision 4068)
@@ -170,5 +170,5 @@
 
     def _repr_defn(self):
-        return repr(self.ring_homomorphism())
+        return str(self.ring_homomorphism())
         
 
@@ -235,6 +235,6 @@
                 raise TypeError, "polys (=%s) must be a list or tuple"%polys
             polys = Sequence(polys)
-            if len(polys) != parent.codomain().ngens():
-                raise ValueError, "there must be %s polynomials"%parent.codomain().ngens()
+            if len(polys) != parent.codomain().ambient_space().ngens():
+                raise ValueError, "there must be %s polynomials"%parent.codomain().ambient_space().ngens()
             polys.set_immutable()
         self.__polys = polys
@@ -361,5 +361,5 @@
             all_zero = True
             for i in range(n):
-                if v[n-1-i]:
+                if v[n-1-i] != 0:
                     all_zero = False
                     c = v[n-1-i]
@@ -370,5 +370,5 @@
                     break
             if all_zero:
-                raise ValueError, "%s does not define a valid point since all entries are 0"%repr(v)
+                raise ValueError, "%s does not define a valid point since all entries are 0"%v
 
             X.codomain()._check_satisfies_equations(v)
@@ -381,5 +381,5 @@
         if isinstance(n, (RingElement, int, long)):
             # [n]*P - multiplication by n.
-            return AdditiveGroupElement._rmul_(self, Integer(n))
+            return AdditiveGroupElement._lmul_(self, Integer(n))
         else:
             # Function composition
Index: sage/schemes/generic/projective_space.py
===================================================================
--- sage/schemes/generic/projective_space.py	(revision 4058)
+++ sage/schemes/generic/projective_space.py	(revision 2047)
@@ -215,5 +215,5 @@
         if v is None:
             v = self.gens()
-        return '(%s)'%(" : ".join([repr(f) for f in v]))
+        return '(%s)'%(" : ".join([str(f) for f in v]))
     
     def _latex_generic_point(self, v=None):
Index: sage/schemes/hyperelliptic_curves/jacobian_morphism.py
===================================================================
--- sage/schemes/hyperelliptic_curves/jacobian_morphism.py	(revision 4059)
+++ sage/schemes/hyperelliptic_curves/jacobian_morphism.py	(revision 2047)
@@ -178,4 +178,4 @@
         return self.__mul__(n)
 
-    def __nonzero__(self):
-        return self.__polys[0] != 1
+    def is_zero(self):
+        return self.__polys[0] == 1
Index: age/server/misc.py
===================================================================
--- sage/server/misc.py	(revision 3889)
+++ 	(revision )
@@ -1,14 +1,0 @@
-def print_open_msg(address, port):
-    s = "Open your web browser to http://%s:%s"%(address, port)
-    t = len(s)
-    if t%2:
-        t += 1
-        s += ' '
-    n = max(t+4, 50)
-    k = n - t  - 1
-    j = k/2 
-    print '*'*n
-    print '*'+ ' '*(n-2) + '*'
-    print '*' + ' '*j + s + ' '*j + '*'
-    print '*'+ ' '*(n-2) + '*'
-    print '*'*n
Index: sage/server/notebook/cell.py
===================================================================
--- sage/server/notebook/cell.py	(revision 3700)
+++ sage/server/notebook/cell.py	(revision 3566)
@@ -482,5 +482,5 @@
             
         s += """
-           <textarea class="%s" rows=%s cols=100000
+           <textarea class="%s" rows=%s cols=100000 columns=100000
               id         = 'cell_input_%s'
               onKeyPress = 'return input_keypress(%s,event);'
@@ -490,10 +490,11 @@
         """%('hidden', r, id, id, id, t)
 
-        t = t.replace("<","&lt;")+" "
+        if r == 0:
+            t = ' '
 
         s += """
            <pre class="%s"
               id         = 'cell_display_%s'
-              onClick  = 'cell_focus(%s, false); return false;'
+              onClick  = 'cell_focus(%s, false); return true;'
            >%s</pre>
         """%(cls, id, id, t)
Index: age/server/notebook/compress/BaseConvert.py
===================================================================
--- sage/server/notebook/compress/BaseConvert.py	(revision 3700)
+++ 	(revision )
@@ -1,53 +1,0 @@
-# BaseConvert class,
-#    converts an unsigned base 10 integer to a different base and vice versa.
-# ______________________________________________________________
-# BaseConvert
-#    |
-#    |________ constructor(newBase:string)
-#    |             uses newBase string var for convertion
-#    |                 [i.e. "0123456789abcdef" for an hex convertion]
-#    |
-#    |________ toBase(unsignedInteger:uint):string
-#    |             return base value of input
-#    |
-#    |________ fromBase(baseString:string):uint
-#                  return base 10 integer value of base input
-# --------------------------------------------------------------
-# @Compatibility	>= Python 2.3
-# @Author		Andrea Giammarchi
-# @Site			http://www.devpro.it/
-# @Date			2006/06/05
-# @Version		1.0
-# @License              GNU General Public License (GPL)
-
-class BaseConvert:
-	
-	__base = ""
-	__baseLength = 0
-	
-	def __init__(self, __base):
-		self.__base = __base
-		self.__baseLength = len(__base)
-	
-	def toBase(self, num):
-		module = 0
-		result = ""
-		while num != 0:
-			module = num % self.__baseLength
-			result = self.__base[module] + result
-			num = int((num - module) / self.__baseLength)
-		if result == "":
-			result = self.__base[0]
-		return result
-
-	
-	def fromBase(self, str):
-		pos = 0
-		strLen = len(str) - 1
-		result = 0
-		while pos < strLen:
-			result = result + (pow(self.__baseLength, strLen - pos) * self.__base.find(str[pos]))
-			pos = pos + 1
-		if strLen >= 0:
-			result = result + self.__base.find(str[pos])
-		return result;
Index: age/server/notebook/compress/JavaScriptCompressor.py
===================================================================
--- sage/server/notebook/compress/JavaScriptCompressor.py	(revision 3700)
+++ 	(revision )
@@ -1,204 +1,0 @@
-# JavaScriptCompressor class,
-#	removes comments or pack JavaScript source[s] code.
-# ______________________________________________________________
-# JavaScriptCompressor (just 2 public methods)
-#    |
-#    |________ self.getClean(jsSource:mixed):string
-#    |         	returns one or more JavaScript code without comments,
-#    |         	by default removes some spaces too
-#    |
-#    |________ self.getPacked(jsSource:mixed):string
-#              	returns one or more JavaScript code packed,
-#	        	using getClean and obfuscating output
-# --------------------------------------------------------------
-# Note about jsSource input varible:
-# 	this var should be a string (i.e. jsSource = "source file string")
-#      should be a list of strings (i.e. ["source file string 1", "source file string 2"])
-#      should be a dictionary with 1 or 2 keys:
-#      	(i.e. {"code":"source file string 1"})
-#              (i.e. {"code":"source file string 1", "name":"mySource"})
-#      ... and should be a list of dictionaries created with theese rules
-#      [
-#		"source javascript 1",
-#              {"code":"source file string 2"},
-#              {"code":"source file string 3", "name":"JSApplication 1.0"}
-#      ]
-#
-#      The name used on dedicated key, will be write on parsed source header
-# --------------------------------------------------------------
-# Note about returned strings:
-# 	Your browser should wrap very long strings, then don't use
-#      cut and paste from your browser, save output into your database or directly
-#      in a file or print them only inside <script> and </script> tags
-# --------------------------------------------------------------
-# Note about JavaScript packed compatibility:
-# 	To be sure about compatibility include before every script JSL Library:
-#      http://www.devpro.it/JSL/
-# JSL library add some features for old or buggy browsers, one of
-# those functions is String.replace with function as second argument,
-# used by JavaScript generated packed code to rebuild original code.
-#
-# Remember that KDE 3.5, Safari and IE5 will not work correctly with packed version
-# if you'll not include JSL.
-# --------------------------------------------------------------
-# @Compatibility	>= Python 2.3
-# @Author		Andrea Giammarchi
-# @Site			http://www.devpro.it/
-# @Date			2006/08/02
-# @LastMOd		2006/08/03 [add __getSize method to have stats like PHP version]
-# @Version		0.1b
-# @Dependencies		Python: BaseConvert.py
-#			Python: SourceMap.py	[ ... I'm waiting that this site will approve SourceMap class ... ]
-#			Client: JSL.js (http://www.devpro.it/JSL/)
-# @Browsers		Convertion is supported by every browser with JSL Library (FF 1+ Opera 8+ and IE5.5+ are supported without JSL too)
-# @Credits		Dean Edwards for his originally idea [dean.edwards.name] and his JavaScript packer
-# @License		GNU General Public License (GPL)
-
-import re, time, string, SourceMap, BaseConvert
-class JavaScriptCompressor:
-	
-	# public variables
-        # 	stats:string		after every compression has some informations
-        #      version:string		version of this class
-	stats = "",
-	version = "0.1";
-
-	# private variables, any comment sorry
-	__startTime = 0
-	__sourceLength = 0
-	__sourceNewLength = 0
-	__totalSources = 0
-	__sources = []
-	__delimeter = [{"name":"doublequote", "start":'"', "end":'"', "noslash":True}, {"name":"singlequote", "start":"'", "end":"'", "noslash":True}, {"name":"singlelinecomment", "start":"//", "end":["\n", "\r"]}, {"name":"multilinecomment", "start":"/*", "end":"*/"}, {"name":"regexp", "start":"/", "end":"/", "match":"^/[^\n\r]+/$", "noslash":True}]
-	__cleanFinder = ["(\n|\r)+", "( |\t)+", "(\n )|( \n)|( \n )", "\s+(\)|})", "(\(|{)\s+", "\s*(;|,|:|<|>|\&|\||\=|\?|\+|\-|\%)\s*", "\)\s+{", "}\s+\("]
-	__cleanReplacer = ["\n", " ", "\n", "\\1", "\\1", "\\1", "){", "}("]
-	__container = []
-	__BC = BaseConvert.BaseConvert("0123456789abcdefghijklmnopqrstuvwxyz")
-	__SourceMap = SourceMap.SourceMap()
-
-	# public method
-        # 	string self.getClean(jsSource:mixed)
-        #      compress JavaScript removing comments and somespaces
-        # @param	mixed		view example and notes on class comments
-	def getClean(self, jsSource):
-		return self.__commonInitMethods(jsSource, False)
-	
-	# public method
-        # 	string self.getClean(jsSource:mixed)
-        #      compress JavaScript replaceing words and removing comments and some spaces
-        # @param	mixed		view example and notes on class comments
-	def getPacked(self, jsSource):
-		return self.__commonInitMethods(jsSource, True)
-	
-	# private methods, any comment sorry
-	def __addCleanCode(self, str):
-		for a in range(0, len(self.__cleanFinder)):
-			str = re.sub(self.__cleanFinder[a], self.__cleanReplacer[a], str)
-		return str
-	def __addslashes(self, str):
-		return str.replace("\\", "\\\\").replace("'", "\'").replace("\"", "\\\"")
-	def __clean(self, str):
-		type = ""
-		clean = []
-		map = self.__SourceMap.getMap(str, self.__delimeter)
-		for a in range(0, len(map)):
-			type = map[a]["name"]
-			if type == "code":
-				clean.append(self.__addCleanCode(str[map[a]["start"]:map[a]["end"]]))
-			elif type == "regexp" or type == "doublequote" or type == "singlequote":
-				clean.append(str[map[a]["start"]:map[a]["end"]])
-			if type != "regexp":
-				clean.append("\n")
-		return re.sub("/(\n)+/", "\n", re.sub("/^\s*|\s*$/", "", string.join(clean, "")))
-	def __commonInitMethods(self, jsSource, packed):
-		header = ""
-		sources = ""
-		tempSources = []
-		self.__startTime = time.clock()
-		self.__sourceLength = 0
-		self.__sourceManager(jsSource)
-		for a in range(0, self.__totalSources):
-			self.__sources[a]["code"] = self.__clean(self.__sources[a]["code"])
-		header = self.__getHeader()
-		for a in range(0, self.__totalSources):
-			tempSources.append(self.__sources[a]["code"])
-		sources = string.join(tempSources, ";")
-		if packed:
-			sources = self.__pack(sources)
-		self.__sourceNewLength = len(sources)
-		self.__setStats()
-		return header + sources
-	def __doReplacement(self, matchobj):
-		return self.__BC.toBase(self.__wordsParser(matchobj.group(0)))	
-	def __getHeader(self):
-		return string.join([
-			"/* ", self.__getScriptNames(), "JavaScriptCompressor ", self.version, " [www.devpro.it], ",
-			"thanks to Dean Edwards for idea [dean.edwards.name]",
-			" */\n"
-		], "")
-	def __getScriptNames(self):
-		a = 0
-		result = []
-		for a in range(0, self.__totalSources):
-			if self.__sources[a]["name"] != "":
-				result.append(self.__sources[a]["name"])
-		a = len(result)
-		if a > 0:
-			a = a - 1
-			result[a] = result[a] + " with ";
-		return string.join(result, ", ")
-	def __getSize(self, size):
-		times = 0
-		fsize = float(size)
-		sizeType = ["bytes", "Kb", "Mb", "Gb", "Tb", "Zb"]
-		sizeTypeLen = len(sizeType)
-		resultSize = ""
-		while fsize > 1024 and times < sizeTypeLen:
-			fsize = fsize / 1024
-			times = times + 1
-		if times > 0:
-			resultSize = "%.2f" % (fsize)
-		else:
-			res