Index: .hgtags
===================================================================
--- .hgtags	(revision 6402)
+++ .hgtags	(revision 6322)
@@ -105,3 +105,2 @@
 78ffd08fed0e3c36107696e55cb6a3323e158758 2.8.4.2.rc1
 49df63f7f26417de37cce57c202a71db075ebf85 2.8.4.2
-56c204456c7552f8c1b80285e32b2a1431e167f0 2.8.4.2.1
Index: c_lib/gmp_globals.c
===================================================================
--- c_lib/gmp_globals.c	(revision 6328)
+++ c_lib/gmp_globals.c	(revision 6226)
@@ -38,5 +38,5 @@
   mpz_clear(x);  mpz_clear(y);
   mpz_clear(sqr);  mpz_clear(m2);
-  mpq_clear(tmp);
+  mpq_init(tmp);
 
   mpz_clear(a1); mpz_clear(a2); mpz_clear(mod1); mpz_clear(mod2);
Index: c_lib/ntl_wrap.cpp
===================================================================
--- c_lib/ntl_wrap.cpp	(revision 6419)
+++ c_lib/ntl_wrap.cpp	(revision 6324)
@@ -219,16 +219,16 @@
 /* Return value is only valid if the result should fit into an int.
    AUTHOR: David Harvey (2008-06-08) */
-int ZZ_p_to_int(const ZZ_p& x )
-{
-  return ZZ_to_int(&rep(x));
+int ZZ_p_to_int(const ZZ_p* x)
+{
+  return ZZ_to_int(&rep(*x));
 }
 
 /* Returns a *new* ZZ_p object.
    AUTHOR: David Harvey (2008-06-08) */
-ZZ_p int_to_ZZ_p(int value)
-{
-  ZZ_p r;
-  r = value;
-  return r;
+struct ZZ_p* int_to_ZZ_p(int value)
+{
+  ZZ_p* output = new ZZ_p();
+  conv(*output, value);
+  return output;
 }
 
@@ -1586,8 +1586,4 @@
 }
 
-void mat_GF2E_SetDims(struct mat_GF2E* m, long nrows, long ncols){
-  m->SetDims(nrows, ncols);
-}
-
 char* mat_GF2E_to_str(mat_GF2E* x) 
 {
Index: c_lib/ntl_wrap.h
===================================================================
--- c_lib/ntl_wrap.h	(revision 6418)
+++ c_lib/ntl_wrap.h	(revision 6239)
@@ -66,8 +66,6 @@
 EXTERN struct ZZ_p* str_to_ZZ_p(const char* s);
 EXTERN char* ZZ_p_to_str(const struct ZZ_p* x);
-#ifdef __cplusplus  // sorry, if you want a C version, feel free to add it
-EXTERN int ZZ_p_to_int(const ZZ_p& x);
-EXTERN ZZ_p int_to_ZZ_p(int value);
-#endif
+EXTERN int ZZ_p_to_int(const struct ZZ_p* x);
+EXTERN struct ZZ_p* int_to_ZZ_p(int value);
 EXTERN void ZZ_p_set_from_int(struct ZZ_p* x, int value);
 EXTERN struct ZZ_p* ZZ_p_add(const struct ZZ_p* x, const struct ZZ_p* y);
@@ -353,5 +351,5 @@
 #endif
 
-EXTERN void mat_GF2E_SetDims(struct mat_GF2E* mGF2E, long nrows, long ncols);
+void mat_GF2E_SetDims(struct mat_GF2E* mGF2E, long nrows, long ncols);
 EXTERN struct mat_GF2E* new_mat_GF2E(long nrows, long ncols);
 EXTERN void del_mat_GF2E(struct mat_GF2E* x);
Index: c_lib/stdsage.h
===================================================================
--- c_lib/stdsage.h	(revision 6387)
+++ c_lib/stdsage.h	(revision 6135)
@@ -62,11 +62,5 @@
     (PyObject_TypeCheck((PyObject*)(zzz_obj), (PyTypeObject*)(zzz_type)))
 
-/** Tests whether zzz_obj is exactly of type zzz_type. The zzz_type must be a
-  * built-in or extension type.  
-  */
-#define PY_TYPE_CHECK_EXACT(zzz_obj, zzz_type) \
-  ((PyTypeObject*)PY_TYPE(zzz_obj) == (PyTypeObject*)(zzz_type))
-  
-  /** Returns the type field of a python object, cast to void*. The
+/** Returns the type field of a python object, cast to void*. The
  *  returned value should only be used as an opaque object e.g. for
  *  type comparisons. 
@@ -81,12 +75,4 @@
     (((PyTypeObject*)(zzz_type))->tp_new((PyTypeObject*)(zzz_type), global_empty_tuple, NULL)) 
 
-  
-  /** Constructs a new object of type the same type as zzz_obj by calling tp_new
-   *  directly, with no arguments. 
-   */
-  
-#define PY_NEW_SAME_TYPE(zzz_obj) \
-  PY_NEW(PY_TYPE(zzz_obj)) 
-  
 /** Resets the tp_new slot of zzz_type1 to point to the tp_new slot of
  *  zzz_type2. This is used in SAGE to speed up Pyrex's boilerplate
Index: sage/algebras/quaternion_algebra_element.py
===================================================================
--- sage/algebras/quaternion_algebra_element.py	(revision 6442)
+++ sage/algebras/quaternion_algebra_element.py	(revision 4450)
@@ -24,5 +24,4 @@
 from sage.rings.polynomial.polynomial_ring import PolynomialRing
 from sage.algebras.free_algebra_quotient_element import FreeAlgebraQuotientElement
-from sage.rings.infinity import Infinity
 
 class QuaternionAlgebraElement(FreeAlgebraQuotientElement):
@@ -38,13 +37,4 @@
     
     def conjugate(self):
-        """
-        Return the conjugate of this element.
-
-        EXAMPLES:
-            sage: A.<i,j,k>=QuaternionAlgebra(QQ,-5,-2)
-            sage: x=3*i-j+2
-            sage: x.conjugate()
-            2 - 3*i + j
-        """
         return self.parent()(self.reduced_trace()) - self        
 	
@@ -53,63 +43,42 @@
         Return the reduced trace of this element.
         
-        \note{In a quaternion algebra $A$, every element $x$ is
-        quadratic over the center, thus $x^2 = \Tr(x)*x - \Nr(x)$, so
-        we solve for a linear relation $(1,-\Tr(x),\Nr(x))$ among
-        $[x^2, x, 1]$ for the reduced trace of $x$.}
-
-        EXAMPLES:
-            sage: A.<i,j,k>=QuaternionAlgebra(QQ,-5,-2)
-            sage: x=3*i-j+2
-            sage: x.reduced_trace()
-            4
-        """
-        v = self.vector()
-        if v[1] == 0 and v[2] == 0 and v[3] == 0: return 2*v[0]
-        u = (self**2).vector()
+	\note{In a quaternion algebra $A$, every element $x$ is
+	quadratic over the center, thus $x^2 = \Tr(x)*x - \Nr(x)$, so
+	we solve for a linear relation $(1,-\Tr(x),\Nr(x))$ among
+	$[x^2, x, 1]$ for the reduced trace of $x$.}
+	"""
+	v = self.vector()
+	if v[1] == 0 and v[2] == 0 and v[3] == 0: return 2*v[0]
+	u = (self**2).vector()
         K = self.parent().base_ring()
-        A = MatrixSpace(K,3,4)	
-        M = A(list(u) + list(v) + [1,0,0,0]).kernel()
-        w = M.gen(0)
-        if w[0] == 1: return -w[1]
+	A = MatrixSpace(K,3,4)	
+	M = A(list(u) + list(v) + [1,0,0,0]).kernel()
+	w = M.gen(0)
+	if w[0] == 1: return -w[1]
         return -w[1]/w[0]
 		
     def reduced_norm(self):
         """
-        Return the reduced norm of this element.
-
-        EXAMPLES:
-            sage: A.<i,j,k>=QuaternionAlgebra(QQ,-5,-2)
-            sage: x=3*i-j+2
-            sage: x.reduced_norm()
-            51
-        """
+	"""
         x = self * self.conjugate()
-        return x.vector()[0]
+	return x.vector()[0]
 
     def charpoly(self, var):
         """
-        Return the characteristic polynomial of this element in terms
-        of the given variable.
-
-        EXAMPLES:
-            sage: A.<i,j,k>=QuaternionAlgebra(QQ,-5,-2)
-            sage: x=3*i-j+2
-            sage: x.charpoly('t')
-            t^2 - 4*t + 51
-        """
-        v = self.vector()
-        if v[1] == 0 and v[2] == 0 and v[3] == 0:
-            return 2*v[0]
-        u = (self**2).vector()
-        A = MatrixSpace(RationalField(),3,4)	
-        M = A(list(u) + list(v) + [1,0,0,0]).kernel()
-        w = M.gen(0)
-        P = PolynomialRing(self.parent().base_ring(), var)
-        x = P.gen()
-        if w[0] == 1:
+	"""
+	v = self.vector()
+	if v[1] == 0 and v[2] == 0 and v[3] == 0:
+	    return 2*v[0]
+	u = (self**2).vector()
+	A = MatrixSpace(RationalField(),3,4)	
+	M = A(list(u) + list(v) + [1,0,0,0]).kernel()
+	w = M.gen(0)
+	P = PolynomialRing(self.parent().base_ring(), var)
+	x = P.gen()
+	if w[0] == 1:
             x**2 + w[1]*x + w[2]
-            return x**2 + w[1]/w[0]*x + w[2]/w[0]
+        return x**2 + w[1]/w[0]*x + w[2]/w[0]
 		
-        return x**2 - self.reduced_trace()*x + self.reduced_norm()
+	return x**2 - self.reduced_trace()*x + self.reduced_norm()
 
     characteristic_polynomial = charpoly
@@ -117,109 +86,15 @@
     def minpoly(self, var):
         """
-        Return the minimal polynomial of this element in terms
-        of the given variable.
-
-        EXAMPLES:
-            sage: A.<i,j,k>=QuaternionAlgebra(QQ,-5,-2)
-            sage: x=3*i-j+2
-            sage: x.minpoly('t')
-            t^2 - 4*t + 51
-        """
-        v = self.vector()
-        if v[1] == 0 and v[2] == 0 and v[3] == 0:
-            K = self.parent().base_ring()
-            P = PolynomialRing(K, var)
-            x = P.gen()
-            return x - v[0]
-        return self.charpoly(var)
+	"""
+	v = self.vector()
+	if v[1] == 0 and v[2] == 0 and v[3] == 0:
+	    K = self.parent().base_ring()
+	    P = PolynomialRing(K, var)
+	    x = P.gen()
+	    return x - v[0]
+	return self.charpoly(var)
 
     minimal_polynomial = minpoly
-
-    def is_unit(self):
-        """
-        Return True if the element is an invertible element of the
-        quaternion algebra.
-
-        EXAMPLES:
-            sage: A.<i,j,k> = QuaternionAlgebra(QQ,-1,-1)
-            sage: i.is_unit()
-            True
-            sage: (i-5+j*k).is_unit()
-            True
-            sage: A(0).is_unit()
-            False
-        """
-        if self.reduced_norm() == 0:
-            return False
-        else:
-            return True
-
-    def additive_order(self):        
-        if self.base_ring().is_finite():
-            return self.base_ring().characteristic()
-        else:
-            return Infinity
-
-    def is_scalar(self):
-        """
-        Return True is this element of a quaternion algebra is
-        a scalar (i.e. lies in the base field).
-
-        EXAMPLES:
-            sage: A.<i,j,k> = QuaternionAlgebra(QQ,-1,-1)
-            sage: i.is_scalar()
-            False
-            sage: (i-5+j*k).is_scalar()
-            False
-            sage: A(12).is_scalar()
-            True
-        """
-        if (self.reduced_trace()-2*self).is_zero():
-            return True
-        else:
-            return False
-
-    def _div_(self, other):
-        """
-        Right division in the quaternion algebra
-
-        EXAMPLES:
-            sage: A.<i,j,k>=QuaternionAlgebra(QQ,-1,-1)
-            sage: x=3*i-j+2
-            sage: y=i-1
-            sage: x/y
-            1/2 - 5/2*i + 1/2*j - 1/2*k
-
-        Note that 1/x will raise an AttributeError.  The way to get
-        the inverse of x is
-            sage: A(1)/x
-            1/7 - 3/14*i + 1/14*j
-        """
-        if other.is_unit() == False:
-            raise AttributeError, "The second operand must be a unit"
-        H = self.parent()
-        if H(other).is_scalar():
-            return QuaternionAlgebraElement(H, [self.vector()[i]/(H(other).reduced_trace()/2) for i in range(4)])
-        elif self.is_scalar():
-            return self*other.conjugate()/other.reduced_norm()
-        else:
-            return self*(H(1)/other)
-
-    def _backslash_(self, other):
-        """
-        Left division in the quaternion algebra
-
-        EXAMPLES:
-            sage: A.<i,j,k>=QuaternionAlgebra(QQ,-1,-1)
-            sage: x=3*i-j+2
-            sage: y=i-1
-            sage: x\y
-            1/14 + 5/14*i - 1/14*j - 1/14*k
-        """
-        if self.is_unit() == False:
-            raise AttributeError, "The first operand must be a unit"
-        else:
-            H = self.parent()
-            return (H(1)/self)*other
+    
 
 class QuaternionAlgebraElement_fast(QuaternionAlgebraElement):
@@ -250,5 +125,4 @@
              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):
Index: sage/calculus/all.py
===================================================================
--- sage/calculus/all.py	(revision 6377)
+++ sage/calculus/all.py	(revision 6312)
@@ -4,5 +4,4 @@
                       is_SymbolicExpressionRing,
                       is_SymbolicExpression,
-                      is_SymbolicVariable,
                       CallableSymbolicExpressionRing,
                       is_CallableSymbolicExpressionRing,
Index: sage/calculus/calculus.py
===================================================================
--- sage/calculus/calculus.py	(revision 6377)
+++ sage/calculus/calculus.py	(revision 6283)
@@ -3043,7 +3043,4 @@
 
 import re
-
-def is_SymbolicVariable(x):
-    return isinstance(x, SymbolicVariable)
 
 class SymbolicVariable(SymbolicExpression):
Index: sage/categories/homset.py
===================================================================
--- sage/categories/homset.py	(revision 6373)
+++ sage/categories/homset.py	(revision 5476)
@@ -55,6 +55,4 @@
         Set of Morphisms from Integer Ring to Rational Field in Category of sets
     """
-    if hasattr(X, '_Hom_'):
-        return X._Hom_(Y, cat)
     import category_types
     global _cache
Index: sage/coding/code_constructions.py
===================================================================
--- sage/coding/code_constructions.py	(revision 6439)
+++ sage/coding/code_constructions.py	(revision 6175)
@@ -71,8 +71,8 @@
             Communication and Computing, 15, (2004), p. 63--79
     """
-    from sage.combinat.all import Tuples
+    from sage.combinat.combinat import tuples
     mset = [x for x in F if x!=0]
     d = len(P[0])
-    pts = Tuples(mset,d).list() 
+    pts = tuples(mset,d) 
     n = len(pts) ## (q-1)^d
     k = len(P)
Index: sage/coding/linear_code.py
===================================================================
--- sage/coding/linear_code.py	(revision 6439)
+++ sage/coding/linear_code.py	(revision 5504)
@@ -190,5 +190,5 @@
 from sage.rings.fraction_field import FractionField
 from sage.rings.integer_ring import IntegerRing
-from sage.combinat.set_partition import SetPartitions
+from sage.combinat.combinat import partitions_set
 
 ZZ = IntegerRing()
@@ -1522,8 +1522,7 @@
         if i>n-dp and i<=n:
             return binomial(n,i)*(q**(i+k-n) -1)/(q-1)
-        P = SetPartitions(J,2).list()
+        P = partitions_set(J,2)
         b = QQ(0)
         for p in P:
-            p = list(p)
             S = p[0]
             if len(S)==n-i:
Index: sage/combinat/all.py
===================================================================
--- sage/combinat/all.py	(revision 6439)
+++ sage/combinat/all.py	(revision 2468)
@@ -2,86 +2,4 @@
 from expnums import expnums
 
-
-
-#Combinatorial Algebra
-from combinatorial_algebra import CombinatorialAlgebra
-
-
-from schubert_polynomial import SchubertPolynomialRing, is_SchubertPolynomial
-from symmetric_group_algebra import SymmetricGroupAlgebra
-
-
-from permutation import Permutation, Permutations, Arrangements, PermutationOptions, CyclicPermutations, CyclicPermutationsOfPartition
-import permutation
-
-#Compositions
-from composition import Composition, Compositions
-import composition
-from composition_signed import SignedCompositions
-
-#Partitions
-import partition
-from partition import Partition, Partitions, PartitionsInBox, OrderedPartitions, RestrictedPartitions, PartitionTuples, PartitionsGreatestLE, PartitionsGreatestEQ
-import skew_partition
-from skew_partition import SkewPartition, SkewPartitions
-from partition_algebra import SetPartitionsAk, SetPartitionsPk, SetPartitionsTk, SetPartitionsIk, SetPartitionsBk, SetPartitionsSk
-
-#Tableaux
-from tableau import Tableau, Tableaux, StandardTableaux, SemistandardTableaux
-import tableau
-from skew_tableau import SkewTableau, StandardSkewTableaux
-import skew_tableau
-from ribbon import Ribbon, StandardRibbonTableaux
-import ribbon
-
-#Words
-from word import Words
-import word
-from subword import Subwords
-import subword
-
-import ranker
-
-#Tuples
-from tuple import Tuples, UnorderedTuples
-
-from alternating_sign_matrix import AlternatingSignMatrices, ContreTableaux, TruncatedStaircases
-
-
-from combination import Combinations
-import combination
-
-
-import choose_nk
-import multichoose_nk
-import permutation_nk
-import split_nk
-from cartesian_product import CartesianProduct
-
-from set_partition import SetPartitions
-import set_partition
-from set_partition_ordered import OrderedSetPartitions
-import set_partition_ordered
-
-import subset
-from subset import Subsets
-
-import q_analogues
-
-import necklace
-from necklace import Necklaces
-from lyndon_word import LyndonWords, StandardBracketedLyndonWords
-import lyndon_word
-
-from dyck_word import DyckWords, DyckWord
-
 from sloane_functions import sloane
 
-
-from sfa import SymmetricFunctionAlgebra, SFAPower, SFASchur, SFAHomogeneous, SFAElementary, SFAMonomial
-
-#import lrcalc
-
-import integer_list
-from integer_vector import IntegerVectors
-from integer_vector_weighted import WeightedIntegerVectors
Index: age/combinat/alternating_sign_matrix.py
===================================================================
--- sage/combinat/alternating_sign_matrix.py	(revision 6439)
+++ 	(revision )
@@ -1,311 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 combinat import CombinatorialClass, CombinatorialObject
-from sage.matrix.matrix_space import MatrixSpace
-from sage.rings.all import ZZ, Integer, factorial
-from sage.sets.set import Set
-from sage.misc.misc import prod
-import copy
-
-def from_contre_tableau(comps):
-    """
-    Returns an alternating sign matrix from a contretableaux.
-
-    TESTS:
-        sage: import sage.combinat.alternating_sign_matrix as asm
-        sage: asm.from_contre_tableau([[1, 2, 3], [1, 2], [1]])
-        [0 0 1]
-        [0 1 0]
-        [1 0 0]
-        sage: asm.from_contre_tableau([[1, 2, 3], [2, 3], [3]])
-        [1 0 0]
-        [0 1 0]
-        [0 0 1]
-    """
-    n = len(comps)
-    MS = MatrixSpace(ZZ, n)
-    M = [ [0 for i in range(n)] for j in range(n) ]
-
-    previous_set = Set([])
-
-    for col in range(n-1, -1, -1):
-        set = Set( comps[col] )
-        for x in set - previous_set:
-            M[x-1][col] = 1
-
-        for x in previous_set - set:
-            M[x-1][col] = -1
-
-        previous_set = set
-
-    return MS(M)
-
-def AlternatingSignMatrices(n):
-    """
-    Returns the combinatorial class of alternating sign matrices of
-    size n.
-
-    EXAMPLES:
-        sage: a2 = AlternatingSignMatrices(2); a2
-        Alternating sign matrices of size 2
-        sage: for a in a2: print a, "-\n"
-        [0 1]
-        [1 0] 
-        -
-        [1 0]
-        [0 1]
-        -
-    """
-    return AlternatingSignMatrices_n(n)
-
-class AlternatingSignMatrices_n(CombinatorialClass):
-    def __init__(self, n):
-        """
-        TESTS:
-            sage: a2 = AlternatingSignMatrices(2); a2
-            Alternating sign matrices of size 2
-            sage: a2 == loads(dumps(a2))
-            True
-        """
-        self.n = n
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(AlternatingSignMatrices(2))
-            'Alternating sign matrices of size 2'
-        """
-        return "Alternating sign matrices of size %s"%self.n
-
-    def count(self):
-        """
-        TESTS:
-            sage: [ AlternatingSignMatrices(n).count() for n in range(0, 11)]
-            [1, 1, 2, 7, 42, 429, 7436, 218348, 10850216, 911835460, 129534272700]
-
-            sage: asms = [ AlternatingSignMatrices(n) for n in range(6) ]
-            sage: all( [ asm.count() == len(asm.list()) for asm in asms] )
-            True
-        """
-        return prod( [ factorial(3*k+1)/factorial(self.n+k) for k in range(self.n)] )
-
-    def iterator(self):
-        """
-
-        TESTS:
-            sage: AlternatingSignMatrices(0).list()
-            [[]]
-            sage: AlternatingSignMatrices(1).list()
-            [[1]]
-            sage: map(list, AlternatingSignMatrices(2).list())
-            [[(0, 1), (1, 0)], [(1, 0), (0, 1)]]
-            sage: map(list, AlternatingSignMatrices(3).list())
-            [[(0, 0, 1), (0, 1, 0), (1, 0, 0)],
-             [(0, 1, 0), (0, 0, 1), (1, 0, 0)],
-             [(0, 0, 1), (1, 0, 0), (0, 1, 0)],
-             [(0, 1, 0), (1, -1, 1), (0, 1, 0)],
-             [(0, 1, 0), (1, 0, 0), (0, 0, 1)],
-             [(1, 0, 0), (0, 0, 1), (0, 1, 0)],
-             [(1, 0, 0), (0, 1, 0), (0, 0, 1)]]
-
-        """
-        for z in ContreTableaux(self.n):
-            yield from_contre_tableau(z)
-
-
-def ContreTableaux(n):
-    """
-    Returns the combinatorial class of contre tableaux of size n.
-
-    EXAMPLES:
-        sage: ct4 = ContreTableaux(4); ct4
-        Contre tableaux of size 4
-        sage: ct4.count()
-        42
-        sage: ct4.first()
-        [[1, 2, 3, 4], [1, 2, 3], [1, 2], [1]]
-        sage: ct4.last()
-        [[1, 2, 3, 4], [2, 3, 4], [3, 4], [4]]
-        sage: ct4.random()  #random
-        [[1, 2, 3, 4], [2, 3, 4], [3, 4], [3]]
-    """
-    return ContreTableaux_n(n)
-
-class ContreTableaux_n(CombinatorialClass):
-    def __init__(self, n):
-        """
-        TESTS:
-            sage: ct2 = ContreTableaux(2); ct2
-            Contre tableaux of size 2
-            sage: ct2 == loads(dumps(ct2))
-            True
-        """
-        self.n = n
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(ContreTableaux(2))
-            'Contre tableaux of size 2'
-        """
-        return "Contre tableaux of size %s"%self.n
-
-    def count(self):
-        """
-        TESTS:
-            sage: [ ContreTableaux(n).count() for n in range(0, 11)]
-            [1, 1, 2, 7, 42, 429, 7436, 218348, 10850216, 911835460, 129534272700]
-        """
-        return prod( [ factorial(3*k+1)/factorial(self.n+k) for k in range(self.n)] )
-
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: ContreTableaux(0).list()     #indirect test
-            [[]]
-            sage: ContreTableaux(1).list()     #indirect test
-            [[[1]]]
-            sage: ContreTableaux(2).list()     #indirect test
-            [[[1, 2], [1]], [[1, 2], [2]]]
-            sage: ContreTableaux(3).list()     #indirect test
-            [[[1, 2, 3], [1, 2], [1]],
-             [[1, 2, 3], [1, 2], [2]],
-             [[1, 2, 3], [1, 3], [1]],
-             [[1, 2, 3], [1, 3], [2]],
-             [[1, 2, 3], [1, 3], [3]],
-             [[1, 2, 3], [2, 3], [2]],
-             [[1, 2, 3], [2, 3], [3]]]
-        """
-        def proc(i):
-            if i == 0:
-                yield []
-            elif i == 1:
-                yield [range(1, self.n+1)]
-
-            else:
-                for columns in proc(i-1):
-                    previous_column = columns[-1]
-                    for column in _next_column_iterator(previous_column, len(previous_column)-1):
-                        yield columns + [ column ]
-
-        for z in proc(self.n):
-            yield z
-
-
-
-
-def _next_column_iterator(previous_column, height):
-    """
-    Returns a generator for all columbs of height height
-    properly filled from row 1 to i
-
-    TESTS:
-        sage: import sage.combinat.alternating_sign_matrix as asm
-        sage: list(asm._next_column_iterator([1], 0))
-        [[]]
-        sage: list(asm._next_column_iterator([1,5],1))
-        [[1], [2], [3], [4], [5]]
-        sage: list(asm._next_column_iterator([1,4,5],2))
-        [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5], [4, 5]]
-    
-    """
-    assert height <= len(previous_column)-1
-    def proc(i):
-        if i == 0:
-            yield [-1]*height
-        else:
-            for column in proc(i-1):
-                min_value = previous_column[i-1]
-                if i > 1:
-                    min_value = max(min_value, column[i-2]+1)
-                for value in range(min_value, previous_column[i]+1):
-                    c = copy.copy(column)
-                    c[i-1] = value
-                    yield c
-
-    for z in proc(height):
-        yield z
-            
-def _previous_column_iterator(column, height, max_value):
-    """
-    TESTS:
-        sage: import sage.combinat.alternating_sign_matrix as asm
-        sage: list(asm._previous_column_iterator([2,3], 3, 4))
-        [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
-    """
-    new_column = [1] + column + [ max_value ] * (height - len(column))
-    return _next_column_iterator(new_column, height)
-        
-def TruncatedStaircases(n, last_column):
-    """
-    Returns the combinatorial class of truncated staircases
-    of size n with last column last_column.
-
-    EXAMPLES:
-        sage: t4 = TruncatedStaircases(4, [2,3]); t4
-        Truncated staircases of size 4 with last column [2, 3]
-        sage: t4.count()
-        4
-        sage: t4.first()
-        [[4, 3, 2, 1], [3, 2, 1], [3, 2]]
-        sage: t4.list()
-        [[[4, 3, 2, 1], [3, 2, 1], [3, 2]], [[4, 3, 2, 1], [4, 2, 1], [3, 2]], [[4, 3, 2, 1], [4, 3, 1], [3, 2]], [[4, 3, 2, 1], [4, 3, 2], [3, 2]]]
-    """
-    return TruncatedStaircases_nlastcolumn(n, last_column)
-
-class TruncatedStaircases_nlastcolumn(CombinatorialClass):
-    def __init__(self, n, last_column):
-        """
-        TESTS:
-            sage: t4 = TruncatedStaircases(4, [2,3]); t4
-            Truncated staircases of size 4 with last column [2, 3]
-            sage: t4 == loads(dumps(t4))
-            True
-        """
-        self.n = n
-        self.last_column = last_column
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(TruncatedStaircases(4, [2,3]))
-            'Truncated staircases of size 4 with last column [2, 3]'
-        """
-        return "Truncated staircases of size %s with last column %s"%(self.n, self.last_column)
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: TruncatedStaircases(4, [2,3]).list() #indirect test
-            [[[4, 3, 2, 1], [3, 2, 1], [3, 2]], [[4, 3, 2, 1], [4, 2, 1], [3, 2]], [[4, 3, 2, 1], [4, 3, 1], [3, 2]], [[4, 3, 2, 1], [4, 3, 2], [3, 2]]]
-
-        """
-        def proc(i):
-            if i < len(self.last_column):
-                return
-            elif i == len(self.last_column):
-                yield [self.last_column]
-            else:
-                for columns in proc(i-1):
-                    previous_column = columns[0]
-                    for column in _previous_column_iterator(previous_column, len(previous_column)+1, self.n):
-                        yield [column] + columns
-
-        for z in proc(self.n):
-            yield map(lambda x: list(reversed(x)), z)
-
-        
Index: age/combinat/cartesian_product.py
===================================================================
--- sage/combinat/cartesian_product.py	(revision 6439)
+++ 	(revision )
@@ -1,142 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 random as rnd
-import __builtin__
-from combinat import CombinatorialClass, CombinatorialObject
-
-
-def CartesianProduct(*iters):
-    """
-    Returns the combinatorial class of the cartesian
-    product of *iters.
-
-    EXAMPLES:
-        sage: cp = CartesianProduct([1,2], [3,4]); cp
-        Cartesian product of [1, 2], [3, 4]
-        sage: cp.list()
-        [[1, 3], [1, 4], [2, 3], [2, 4]]
-    """
-    return CartesianProduct_iters(*iters)
-
-class CartesianProduct_iters(CombinatorialClass):
-    def __init__(self, *iters):
-        """
-        TESTS:
-            sage: import sage.combinat.cartesian_product as cartesian_product
-            sage: cp = cartesian_product.CartesianProduct_iters([1,2],[3,4]); cp
-            Cartesian product of [1, 2], [3, 4]
-            sage: loads(dumps(cp)) == cp
-            True
-        """
-        self.iters = iters
-
-    def __repr__(self):
-        """
-        EXAMPLES:
-            sage: CartesianProduct(range(2), range(3))
-            Cartesian product of [0, 1], [0, 1, 2]
-        """
-        return "Cartesian product of " + ", ".join(map(str, self.iters))
-
-    def count(self):
-        """
-        Returns the number of elements in the cartesian product of
-        everything in *iters.
-
-        EXAMPLES:
-            sage: CartesianProduct(range(2), range(3)).count()
-            6
-            sage: CartesianProduct(range(2), xrange(3)).count()
-            6
-            sage: CartesianProduct(range(2), xrange(3), xrange(4)).count()
-            24
-        """
-        total = 1
-        for it in self.iters:
-            total *= len(it)
-        return total
-
-    
-    def list(self):
-        """
-        Returns
-
-        EXAMPLES:
-            sage: CartesianProduct(range(3), range(3)).list()
-            [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
-            sage: CartesianProduct('dog', 'cat').list()
-            [['d', 'c'],
-             ['d', 'a'],
-             ['d', 't'],
-             ['o', 'c'],
-             ['o', 'a'],
-             ['o', 't'],
-             ['g', 'c'],
-             ['g', 'a'],
-             ['g', 't']]
-        """
-        return [e for e in self.iterator()]
-
-
-    def iterator(self):
-        """
-        An iterator for the elements in the cartesian product
-        of the iterables *iters.
-
-        From Recipe 19.9 in the Python Cookbook by Alex Martelli
-        and David Ascher.
-
-        EXAMPLES:
-            sage: [e for e in CartesianProduct(range(3), range(3))]
-            [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
-            sage: [e for e in CartesianProduct('dog', 'cat')]
-            [['d', 'c'],
-             ['d', 'a'],
-             ['d', 't'],
-             ['o', 'c'],
-             ['o', 'a'],
-             ['o', 't'],
-             ['g', 'c'],
-             ['g', 'a'],
-             ['g', 't']]
-        """
-
-        # visualize an odometer, with "wheels" displaying "digits"...:
-        wheels = map(iter, self.iters)
-        digits = [it.next() for it in wheels]
-        while True:
-            yield __builtin__.list(digits)
-            for i in range(len(digits)-1, -1, -1):
-                try:
-                    digits[i] = wheels[i].next()
-                    break
-                except StopIteration:
-                    wheels[i] = iter(self.iters[i])
-                    digits[i] = wheels[i].next()
-            else:
-                break
-
-    def random(self):
-        """
-        Returns a random element from the cartesian product
-        of *iters.
-
-        EXAMPLES:
-            sage: CartesianProduct('dog', 'cat').random() #random
-            ['d', 'c']
-        """
-
-        return list(map(rnd.choice, self.iters))
Index: age/combinat/choose_nk.py
===================================================================
--- sage/combinat/choose_nk.py	(revision 6439)
+++ 	(revision )
@@ -1,207 +1,0 @@
-from sage.rings.arith import binomial
-import random as rnd
-from combinat import CombinatorialClass
-
-def ChooseNK(n, k):
-    return ChooseNK_nk(n,k)
-
-class ChooseNK_nk(CombinatorialClass):
-    def __init__(self, n, k):
-        self.n = n
-        self.k = k
-
-        
-    def count(self):
-        """
-        Returns the number of choices of k things from a list
-        of n things.
-
-        EXAMPLES:
-            sage: from sage.combinat.choose_nk import ChooseNK
-            sage: ChooseNK(3,2).count()
-            3
-            sage: ChooseNK(5,2).count()
-            10
-        """
-        return binomial(self.n, self.k)
-
-    def iterator(self):
-        """
-        An iterator for all choies of k thinkgs from range(n).
-
-        EXAMPLES:
-            sage: from sage.combinat.choose_nk import ChooseNK
-            sage: [c for c in ChooseNK(5,2)]
-            [[0, 1],
-             [0, 2],
-             [0, 3],
-             [0, 4],
-             [1, 2],
-             [1, 3],
-             [1, 4],
-             [2, 3],
-             [2, 4],
-             [3, 4]]
-        """
-        k = self.k
-        n = self.n
-        dif = 1
-        if k == 0:
-            yield []
-            return
-
-        if n < 1+(k-1)*dif:
-            return
-        else:
-            subword = [ i*dif for i in range(k) ]
-
-        yield subword[:]
-        finished = False
-
-        while not finished:    
-            #Find the biggest element that can be increased
-            if subword[-1] < n-1:
-                subword[-1] += 1
-                yield subword[:]
-                continue
-
-            finished = True
-            for i in reversed(range(k-1)):
-                if subword[i]+dif < subword[i+1]:
-                    subword[i] += 1
-                    #Reset the bigger elements
-                    for j in range(1,k-i):
-                        subword[i+j] = subword[i]+j*dif
-                    yield subword[:]
-                    finished = False
-                    break
-
-        return 
-        
-
-    def random(self):
-        """
-        Returns a random choice of k things from range(n).
-
-        EXAMPLES:
-            sage: from sage.combinat.choose_nk import ChooseNK
-            sage: ChooseNK(5,2).random() #random
-            [0,3]
-        """
-        r = rnd.sample(xrange(self.n),self.k)
-        r.sort()
-        return r
-
-
-def rank(comb, n):
-    """
-    Returns the rank of comb in the subsets of range(n) of
-    size k.
-
-    The algorithm used is based on combinadics and James
-    McCaffrey's MSDN article.
-    See: http://en.wikipedia.org/wiki/Combinadic
-
-    EXAMPLES:
-        sage: import sage.combinat.choose_nk as choose_nk
-        sage: choose_nk.rank([], 3)
-        0
-        sage: choose_nk.rank([0], 3)
-        0
-        sage: choose_nk.rank([1], 3)
-        1
-        sage: choose_nk.rank([2], 3)
-        2
-        sage: choose_nk.rank([0,1], 3)
-        0
-        sage: choose_nk.rank([0,2], 3)
-        1
-        sage: choose_nk.rank([1,2], 3)
-        2
-        sage: choose_nk.rank([0,1,2], 3)
-        0        
-    """
-
-    k = len(comb)
-    if k > n:
-        raise ValueError, "len(comb) must be <= n"
-    
-    #Generate the combinadic from the
-    #combination
-    w = [0]*k
-    for i in range(k):
-        w[i] = (n-1) - comb[i]
-
-    #Calculate the integer that is the dual of
-    #the lexicographic index of the combination
-    r = k
-    t = 0
-    for i in range(k):
-        t += binomial(w[i],r)
-        r -= 1
-
-    return binomial(n,k)-t-1
-
-
-
-def _comb_largest(a,b,x):
-    """
-    Helper function for from_rank.
-    """
-    w = a - 1
-
-    while binomial(w,b) > x:
-        w -= 1
-
-    return w
-
-def from_rank(r, n, k):
-    """
-    Returns the combination of rank r in the subsets of range(n)
-    of size k when listed in lexicographic order.
-
-    The algorithm used is based on combinadics and James
-    McCaffrey's MSDN article. 
-    See: http://en.wikipedia.org/wiki/Combinadic
-
-
-    EXAMPLES:
-        sage: import sage.combinat.choose_nk as choose_nk
-        sage: choose_nk.from_rank(0,3,0)
-        []
-        sage: choose_nk.from_rank(0,3,1)
-        [0]
-        sage: choose_nk.from_rank(1,3,1)
-        [1]
-        sage: choose_nk.from_rank(2,3,1)
-        [2]
-        sage: choose_nk.from_rank(0,3,2)
-        [0, 1]
-        sage: choose_nk.from_rank(1,3,2)
-        [0, 2]
-        sage: choose_nk.from_rank(2,3,2)
-        [1, 2]
-        sage: choose_nk.from_rank(0,3,3)
-        [0, 1, 2]
-    """
-    if k < 0:
-        raise ValueError, "k must be > 0"
-    if k > n:
-        raise ValueError, "k must be <= n"
-    
-    a = n
-    b = k
-    x = binomial(n,k) - 1 - r # x is the 'dual' of m
-    comb = [None]*k
-
-    for i in range(k):
-        comb[i] = _comb_largest(a,b,x)
-        x = x - binomial(comb[i], b)
-        a = comb[i]
-        b = b -1
-
-    for i in range(k):
-        comb[i] = (n-1)-comb[i]
-
-    return comb
-
Index: sage/combinat/combinat.py
===================================================================
--- sage/combinat/combinat.py	(revision 6459)
+++ sage/combinat/combinat.py	(revision 5805)
@@ -6,6 +6,8 @@
         -- William Stein (2006-07), editing of docs and code; many optimizations,
                       refinements, and bug fixes in corner cases
-        -- DJ (2006-09): bug fix for combinations, added permutations_iterator,
-                      combinations_iterator from Python Cookbook, edited docs.
+        -- David Joyner (2006-09): bug fix for combinations, added
+                      permutations_iterator, combinations_iterator
+                      from Python Cookbook, edited docs.
+        -- Bobby Moretti (2007-05) added a lazy fibonacci sequence generator
                       
 This module implements some combinatorial functions, as listed
@@ -16,101 +18,108 @@
 \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}.  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:
@@ -174,6 +183,5 @@
 
 #*****************************************************************************
-#       Copyright (C) 2006 David Joyner <wdjoyner@gmail.com>,
-#                     2007 Mike Hansen <mhansen@gmail.com>,
+#       Copyright (C) 2006 David Joyner <wdjoyner@gmail.com>, 
 #                     2006 William Stein <wstein@gmail.com>
 #
@@ -195,27 +203,27 @@
 from sage.misc.sage_eval import sage_eval
 from sage.libs.all import pari
-from sage.rings.arith import factorial
-from random import randint
-from sage.misc.misc import prod
-from sage.structure.sage_object import SageObject
-import __builtin__
-from sage.algebras.algebra import Algebra
-from sage.algebras.algebra_element import AlgebraElement
-import sage.structure.parent_base
+
+import expnums
 import partitions as partitions_ext
 
 ######### combinatorial sequences
 
-def bell_number(n):
+def bell_number(n, algorithm='sage'):
     r"""
     Returns the n-th Bell number (the number of ways to partition a
     set of n elements into pairwise disjoint nonempty subsets).
 
+    INPUT:
+        n -- an integer
+        algorithm -- 'sage': use N. Alexander's custom implementation in SAGE
+                     'gap': use Gap's Bell command (slow)
+
     If $n \leq 0$, returns $1$.
-    
-    Wraps GAP's Bell.
+
     
     EXAMPLES:
         sage: bell_number(10)
+        115975
+        sage: bell_number(10, algorithm='gap')
         115975
         sage: bell_number(2)
@@ -229,7 +237,20 @@
         ...
         TypeError: no coercion of this rational to integer
-    """
-    ans=gap.eval("Bell(%s)"%ZZ(n))
-    return ZZ(eval(ans))
+
+    To compute all Bell numbers up to n, use expnums:
+        sage: expnums(10,1)
+        [1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147]
+        sage: [bell_number(n) for n in range(10)]
+        [1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147]
+    """
+    n = ZZ(n)
+    if n <= 0:
+        return ZZ(1)
+    if algorithm == 'sage':
+        return expnums.expnums(n+1,1)[-1]
+    elif algorithm == 'gap':
+        return ZZ(gap.eval("Bell(%s)"%ZZ(n)))
+    else:
+        raise ValueError, "unknown algorithm '%s'"%algorithm
 
 ## def bernoulli_number(n):
@@ -248,4 +269,7 @@
     r"""
     Returns the n-th Catalan number 
+
+    INPUT:
+        n -- an integer
 
       Catalan numbers: The $n$-th Catalan number is given directly in terms of 
@@ -291,4 +315,7 @@
     Returns the n-th Euler number
 
+    INPUT:
+        n -- an integer
+
     IMPLEMENTATION: Wraps Maxima's euler.
     
@@ -315,9 +342,10 @@
 def fibonacci(n, algorithm="pari"):
     """
-    Returns then n-th Fibonacci number. The Fibonacci sequence $F_n$
-    is defined by the initial conditions $F_1=F_2=1$ and the
-    recurrence relation $F_{n+2} = F_{n+1} + F_n$. For negative $n$ we
-    define $F_n = (-1)^{n+1}F_{-n}$, which is consistent with the
-    recurrence relation.
+    Returns then n-th Fibonacci number.
+
+    The Fibonacci sequence $F_n$ is defined by the initial conditions
+    $F_1=F_2=1$ and the recurrence relation $F_{n+2} = F_{n+1} +
+    F_n$. For negative $n$ we define $F_n = (-1)^{n+1}F_{-n}$, which
+    is consistent with the recurrence relation.
 
     For negative $n$, define $F_{n} = -F_{|n|}$.
@@ -357,4 +385,96 @@
     else:
         raise ValueError, "no algorithm %s"%algorithm
+
+def fibonacci_sequence(start, stop=None, algorithm=None):
+    r"""
+    Returns an iterator over the Fibonacci sequence, for all fibonacci numbers
+    $f_n$ from \code{n = start} up to (but not including) \code{n = stop}
+
+    INPUT:
+        start -- starting value 
+        stop -- stopping value
+        algorithm -- default (None) -- passed on to fibonacci function (or
+                     not passed on if None, i.e., use the default).
+        
+
+    EXAMPLES:
+        sage: fibs = [i for i in fibonacci_sequence(10, 20)]
+        sage: fibs
+        [55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
+
+        sage: sum([i for i in fibonacci_sequence(100, 110)])
+        69919376923075308730013
+
+    SEE ALSO: fibonacci_xrange
+
+    AUTHOR:
+        Bobby Moretti
+    """
+    from sage.rings.integer_ring import ZZ
+    if stop is None:
+        stop = ZZ(start)
+        start = ZZ(0)
+    else:
+        start = ZZ(start)
+        stop = ZZ(stop)
+
+    if algorithm:
+        for n in xrange(start, stop):
+            yield fibonacci(n, algorithm=algorithm)
+    else:
+        for n in xrange(start, stop):
+            yield fibonacci(n)
+
+def fibonacci_xrange(start, stop=None, algorithm='pari'):
+    r"""
+    Returns an iterator over all of the Fibonacci numbers in the given range,
+    including \code{f_n = start} up to, but not including, \code{f_n = stop}.
+    
+    EXAMPLES:
+        sage: fibs_in_some_range =  [i for i in fibonacci_xrange(10^7, 10^8)]
+        sage: len(fibs_in_some_range)
+        4
+        sage: fibs_in_some_range
+        [14930352, 24157817, 39088169, 63245986]
+
+        sage: fibs = [i for i in fibonacci_xrange(10, 100)]
+        sage: fibs
+        [13, 21, 34, 55, 89]
+
+        sage: list(fibonacci_xrange(13, 34))
+        [13, 21]
+
+    A solution to the second Project Euler problem:
+        sage: sum([i for i in fibonacci_xrange(10^6) if is_even(i)])
+        1089154
+
+    SEE ALSO: fibonacci_sequence
+
+    AUTHOR:
+        Bobby Moretti
+    """
+    from sage.rings.integer_ring import ZZ
+    if stop is None:
+        stop = ZZ(start)
+        start = ZZ(0)
+    else:
+        start = ZZ(start)
+        stop = ZZ(stop)
+
+    # iterate until we've gotten high enough
+    fn = 0
+    n = 0
+    while fn < start:
+        n += 1
+        fn = fibonacci(n)
+
+    while True:
+        fn = fibonacci(n)
+        n += 1
+        if fn < stop:
+            yield fn
+        else:
+            return
+
 
 def lucas_number1(n,P,Q):
@@ -461,7 +581,7 @@
 def stirling_number1(n,k):
     """
-    Returns the n-th Stilling number $S_1(n,k)$ of the first kind (the number of 
-    permutations of n points with k cycles). 
-    Wraps GAP's Stirling1.
+    Returns the n-th Stilling number $S_1(n,k)$ of the first kind (the
+    number of permutations of n points with k cycles).  Wraps GAP's
+    Stirling1.
     
     EXAMPLES:
@@ -502,331 +622,4 @@
     return ZZ(gap.eval("Stirling2(%s,%s)"%(ZZ(n),ZZ(k))))
 
-def mod_stirling(q,n,k):
-    """
-    """
-    if k>n or k<0 or n<0:
-        raise ValueError, "n (= %s) and k (= %s) must greater than or equal to 0, and n must be greater than or equal to k"
-
-    if k == 0:
-        return 1
-    elif k == 1:
-        return (n**2+(2*q+1)*n)/2
-    elif k == n:
-        return prod( [ q+i for i in range(1, n+1) ] )
-    else:
-        return mod_stirling(q,n-1,k)+(q+n)*mod_stirling(q, n-1, k-1)
-    
-
-
-
-class CombinatorialObject(SageObject):
-    def __init__(self, l):
-        self.list = l
-
-    def __str__(self):
-        return str(self.list)
-
-    def __repr__(self):
-        return self.list.__repr__()
-    
-    def __eq__(self, other):
-        if isinstance(other, CombinatorialObject):
-            return self.list.__eq__(other.list)
-        else:
-            return self.list.__eq__(other)
-
-    def __lt__(self, other):
-        if isinstance(other, CombinatorialObject):
-            return self.list.__lt__(other.list)
-        else:
-            return self.list.__lt__(other)
-
-    def __le__(self, other):
-        if isinstance(other, CombinatorialObject):
-            return self.list.__le__(other.list)
-        else:
-            return self.list.__le__(other)
-
-    def __gt__(self, other):
-        if isinstance(other, CombinatorialObject):
-            return self.list.__gt__(other.list)
-        else:
-            return self.list.__gt__(other)
-
-    def __ge__(self, other):
-        if isinstance(other, CombinatorialObject):
-            return self.list.__ge__(other.list)
-        else:
-            return self.list.__ge__(other)
-
-    def __ne__(self, other):
-        if isinstance(other, CombinatorialObject):
-            return self.list.__ne__(other.list)
-        else:
-            return self.list.__ne__(other)
-
-    def __add__(self, other):
-        return self.list + other
-
-    def __hash__(self):
-        return str(self.list).__hash__()
-
-    #def __cmp__(self, other):
-    #    return self.list.__cmp__(other)
-
-    def __len__(self):
-        return self.list.__len__()
-
-    def __getitem__(self, key):
-        return self.list.__getitem__(key)
-
-    def __iter__(self):
-        return self.list.__iter__()
-
-    def __contains__(self, item):
-        return self.list.__contains__(item)
-
-
-    def index(self, key):
-        return self.list.index(key)
-    
-
-class CombinatorialClass(SageObject):
-
-    def __len__(self):
-        return self.count()
-
-    def __getitem__(self, i):
-        return self.unrank(i)
-
-    def __str__(self):
-        return self.__repr__()
-    
-    def __repr__(self):
-        return "Combinatorial Class"
-
-    def __contains__(self, x):
-        return False
-
-    def __iter__(self):
-        return self.iterator()
-
-    def __cmp__(self, x):
-        return cmp(repr(self), repr(x))
-    
-    def __count_from_iterator(self):
-        c = 0
-        for x in self.iterator():
-            c += 1
-        return c
-    count = __count_from_iterator
-
-    def __call__(self, x):
-        if x in self:
-            return self.object_class(x)
-        else:
-            raise ValueError, "%s not in %s"%(x, self)
-
-    def __list_from_iterator(self):
-        res = []
-        for x in self.iterator():
-            res.append(x)
-        return res
-
-    list  = __list_from_iterator
-
-    object_class = CombinatorialObject
-
-    def __iterator_from_next(self):
-        f = self.first()
-        yield f
-        while True:
-            try:
-                f = self.next(f)
-            except:
-                break
-            
-            if f == None:
-                break
-            else:
-                yield f
-                
-    def __iterator_from_previous(self):
-        l = self.last()
-        yield l
-        while True:
-            try:
-                l = self.previous(l)
-            except:
-                break
-            
-            if l == None:
-                break
-            else:
-                yield l
-                
-    def __iterator_from_unrank(self):
-        r = 0
-        u = self.unrank(r)
-        yield f
-        while True:
-            r += 1
-            try:
-                u = self.unrank(l)
-            except:
-                break
-            
-            if u == None:
-                break
-            else:
-                yield u
-
-    def __iterator_from_list(self):
-        for x in self.list():
-            yield x
-            
-    def iterator(self):
-        if ( self.first != self.__first_from_iterator and
-             self.next  != self.__next_from_iterator ):
-            return self.__iterator_from_next()
-        elif ( self.last != self.__last_from_iterator and
-               self.previous != self.__previous_from_iterator):
-            return self.__iterator_from_previous()
-        elif self.unrank != self.__unrank_from_iterator:
-            return self.__iterator_from_unrank()
-        elif self.list != self.__list_from_iterator:
-            return self.__iterator_from_list()
-        else:
-            raise NotImplementedError, "iterator called but not implemented"
-
-
-    def __list_from_unrank_and_count(self):
-        return [ self.unrank(i) for i in range(self.count()) ]
-
-    def __unrank_from_iterator(self, r):
-        counter = 0
-        for u in self.iterator():
-            if counter == r:
-                return u
-            counter += 1
-        raise ValueError, "the value must be between %s and %s inclusive"%(0,counter-1)
-
-    def __unrank_from_iterator(self, r):
-        counter = 0
-        for u in self.iterator():
-            if counter == r:
-                return u
-            counter += 1
-
-    unrank = __unrank_from_iterator
-
-    def __random_from_unrank(self):
-        c = self.count()
-        r = randint(0, c-1)
-        if hasattr(self, 'object_class'):
-            return self.object_class(self.unrank(r))
-        else:
-            return self.unrank(r)
-
-    random = __random_from_unrank
-
-
-    def __rank_from_iterator(self, obj):
-        r = 0
-        for i in self.iterator():
-            if i == obj:
-                return r
-            r += 1
-            
-    rank =  __rank_from_iterator
-
-    def __first_from_iterator(self):
-        for i in self.iterator():
-            return i
-
-    first = __first_from_iterator
-
-    def __last_from_iterator(self):
-        for i in self.iterator():
-            pass
-        return i
-
-    last = __last_from_iterator
-
-    def __next_from_iterator(self, obj):
-        if hasattr(obj, 'next'):
-            res = obj.next()
-            if res:
-                return res
-            else:
-                return None
-        found = False
-        for i in self.iterator():
-            if found:
-                return i
-            if i == obj:
-                found = True
-        return None
-
-    next = __next_from_iterator
-
-    def __previous_from_iterator(self, obj):
-        if hasattr(obj, 'previous'):
-            res = obj.previous()
-            if res:
-                return res
-            else:
-                return None
-        prev = None
-        for i in self.iterator():
-            if i == obj:
-                break
-            prev = i
-        return prev
-
-    previous = __previous_from_iterator
-
-def hurwitz_zeta(s,x,N):
-    """
-    Returns the value of the $\zeta(s,x)$ to $N$ decimals, where s and x are real.
-
-    The Hurwitz zeta function is one of the many zeta functions. It defined as
-    \[
-    \zeta(s,x) = \sum_{k=0}^\infty (k+x)^{-s}.
-    \]
-    When $x = 1$, this coincides with Riemann's zeta function. The Dirichlet L-functions 
-    may be expressed as a linear combination of Hurwitz zeta functions.
-
-    EXAMPLES:
-        sage: hurwitz_zeta(3,1/2,6)
-        8.41439000000000
-        sage: hurwitz_zeta(1.1,1/2,6)
-        12.1041000000000
-        sage: hurwitz_zeta(1.1,1/2,50)
-        12.103813495683744469025853545548130581952676591199
-
-    REFERENCES:
-        http://en.wikipedia.org/wiki/Hurwitz_zeta_function
-
-    """
-    maxima.eval('load ("bffac")')
-    s = maxima.eval("bfhzeta (%s,%s,%s)"%(s,x,N))
-
-    #Handle the case where there is a 'b' in the string
-    #'1.2000b0' means 1.2000 and
-    #'1.2000b1' means 12.000
-    i = s.rfind('b')
-    if i == -1:
-        return sage_eval(s)
-    else:
-        if s[i+1:] == '0':
-            return sage_eval(s[:i])
-        else:
-            return sage_eval(s[:i])*10**sage_eval(s[i+1:])
-    
-    return s  ## returns an odd string
-
-
-#####################################################
 #### combinatorial sets/lists
 
@@ -1963,2 +1756,54 @@
     ans=gap.eval("AssociatedPartition(%s)"%(pi))
     return eval(ans)
+
+## related functions
+
+def bernoulli_polynomial(x,n):
+    r"""
+    The generating function for the Bernoulli polynomials is
+    \[
+     \frac{t e^{xt}}{e^t-1}= \sum_{n=0}^\infty B_n(x) \frac{t^n}{n!}. 
+    \]
+
+    One has $B_n(x) = - n\zeta(1 - n,x)$, where $\zeta(s,x)$ is the
+    Hurwitz zeta function.  Thus, in a certain sense, the Hurwitz zeta
+    generalizes the Bernoulli polynomials to non-integer values of n.
+
+    EXAMPLES:
+        sage: y = QQ['y'].0
+        sage: bernoulli_polynomial(y,5)
+        y^5 - 5/2*y^4 + 5/3*y^3 - 1/6*y
+
+    REFERENCES:
+        http://en.wikipedia.org/wiki/Bernoulli_polynomials
+    """
+    return sage_eval(maxima.eval("bernpoly(x,%s)"%n), {'x':x})
+
+
+#def hurwitz_zeta(s,x,N):
+#    """
+#    Returns the value of the $\zeta(s,x)$ to $N$ decimals, where s and x are real.
+#
+#    The Hurwitz zeta function is one of the many zeta functions. It defined as
+#    \[
+#    \zeta(s,x) = \sum_{k=0}^\infty (k+x)^{-s}.
+#    \]
+#    When $x = 1$, this coincides with Riemann's zeta function. The Dirichlet L-functions 
+#    may be expressed as a linear combination of Hurwitz zeta functions.
+#
+#    EXAMPLES:
+#        sage: hurwitz_zeta(3,1/2,6)
+#        '8.41439b0'
+#        sage: hurwitz_zeta(1.1,1/2,6)
+#        'Warning:Floattobigfloatconversionof12.1040625294406841.21041b1'
+#
+#    "b0" can be ignored, but "b1" means that the decimal point was shifted 
+#    1 to the left (so the answer is not 1.21041b1 but 12.10406).
+#
+#    REFERENCES:
+#        http://en.wikipedia.org/wiki/Hurwitz_zeta_function
+#
+#    """
+#    maxima.eval('load ("bffac")')
+#    s = maxima.eval("bfhzeta (%s,%s,%s)"%(s,x,N))
+#    return s  ## returns an odd string
Index: age/combinat/combination.py
===================================================================
--- sage/combinat/combination.py	(revision 6439)
+++ 	(revision )
@@ -1,179 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.interfaces.all import gap
-from sage.rings.all import QQ, RR, ZZ
-from combinat import CombinatorialObject, CombinatorialClass
-
-def Combinations(mset, k=None):
-    """
-    Returns the combinatorial class of combinations of mset. If
-    k is specified, then it returns the the combintorial class
-    of combinations of mset of size k.
-
-    The combinatorial classes correctly handle the cases where
-    mset has duplicate elements.
-
-    EXAMPLES:
-        sage: C = Combinations(range(4)); C
-        Combinations of [0, 1, 2, 3]
-        sage: C.list()
-        [[],
-         [0],
-         [1],
-         [2],
-         [3],
-         [0, 1],
-         [0, 2],
-         [0, 3],
-         [1, 2],
-         [1, 3],
-         [2, 3],
-         [0, 1, 2],
-         [0, 1, 3],
-         [0, 2, 3],
-         [1, 2, 3],
-         [0, 1, 2, 3]]
-         sage: C.count()
-         16
-         
-         sage: C2 = Combinations(range(4),2); C2
-         Combinations of [0, 1, 2, 3] of length 2
-         sage: C2.list()
-         [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]
-         sage: C2.count()
-         6
-
-         sage: Combinations([1,2,2,3]).list()
-         [[],
-          [1],
-          [2],
-          [3],
-          [1, 2],
-          [1, 3],
-          [2, 2],
-          [2, 3],
-          [1, 2, 2],
-          [1, 2, 3],
-          [2, 2, 3],
-          [1, 2, 2, 3]]
-    """
-    if k is None:
-        return Combinations_mset(mset)
-    else:
-        return Combinations_msetk(mset,k)
-
-class Combinations_mset(CombinatorialClass):
-    def __init__(self, mset):
-        """
-        TESTS:
-            sage: C = Combinations(range(4))
-            sage: C == loads(dumps(C))
-            True
-        """
-        self.mset = mset
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Combinations(range(4)))
-            'Combinations of [0, 1, 2, 3]'
-        """
-        return "Combinations of %s"%self.mset
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: Combinations([1,2,3]).list() #indirect test
-            [[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
-            sage: Combinations(['a','a','b']).list() #indirect test
-            [[], ['a'], ['b'], ['a', 'a'], ['a', 'b'], ['a', 'a', 'b']]
-        """
-        for k in range(len(self.mset)+1):
-            for comb in Combinations_msetk(self.mset, k):
-                yield comb
-
-    def count(self):
-        """
-        TESTS:
-            sage: Combinations([1,2,3]).count()
-            8
-            sage: Combinations(['a','a','b']).count()
-            6
-        """
-        c = 0
-        for k in range(len(self.mset)+1):
-            c +=  Combinations_msetk(self.mset, k).count()
-        return c
-
-
-class Combinations_msetk(CombinatorialClass):
-    def __init__(self, mset, k):
-        """
-        TESTS:
-            sage: C = Combinations([1,2,3],2)
-            sage: C == loads(dumps(C))
-            True
-        """
-        self.mset = mset
-        self.k = k
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Combinations([1,2,3],2))
-            'Combinations of [1, 2, 3] of length 2'
-        """
-        return "Combinations of %s of length %s"%(self.mset, self.k)
-    
-    def list(self):
-        """
-        Wraps GAP's Combinations.
-        EXAMPLES:
-            sage: Combinations([1,2,3,4,5],3).list()
-            [[1, 2, 3],
-             [1, 2, 4],
-             [1, 2, 5],
-             [1, 3, 4],
-             [1, 3, 5],
-             [1, 4, 5],
-             [2, 3, 4],
-             [2, 3, 5],
-             [2, 4, 5],
-             [3, 4, 5]]
-            sage: Combinations(['a','a','b'],2).list()
-            [['a', 'a'], ['a', 'b']]
-        """
-        def label(x):
-            return self.mset[x]
-
-        items = map(self.mset.index, self.mset)
-        ans=eval(gap.eval("Combinations(%s,%s)"%(items,ZZ(self.k))).replace("\n",""))
-
-        return map(lambda x: map(label, x), ans)
-        
-
-    def count(self):
-        """
-        Returns the size of combinations(mset,k).
-        IMPLEMENTATION: Wraps GAP's NrCombinations.
-
-        EXAMPLES:
-            sage: mset = [1,1,2,3,4,4,5]
-            sage: Combinations(mset,2).count()
-            12
-        """
-        items = map(self.mset.index, self.mset)
-        return ZZ(gap.eval("NrCombinations(%s,%s)"%(items,ZZ(self.k))))
Index: age/combinat/combinatorial_algebra.py
===================================================================
--- sage/combinat/combinatorial_algebra.py	(revision 6439)
+++ 	(revision )
@@ -1,328 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.interfaces.all import gap, maxima
-from sage.rings.all import QQ, RR, ZZ
-from sage.rings.arith import binomial
-from sage.misc.sage_eval import sage_eval
-from sage.libs.all import pari
-from sage.rings.all import Ring, factorial, Integer
-from random import randint
-from sage.misc.misc import prod, repr_lincomb
-from sage.structure.sage_object import SageObject
-import __builtin__
-from sage.algebras.algebra import Algebra
-from sage.algebras.algebra_element import AlgebraElement
-import sage.structure.parent_base
-
-
-class CombinatorialAlgebraElement(AlgebraElement):
-    def __init__(self, A, x):
-        """
-        """
-        AlgebraElement.__init__(self, A)
-        self._monomial_coefficients = x
-
-
-    def monomial_coefficients(self):
-        return self._monomial_coefficients
-    
-    def _repr_(self):
-        v = self._monomial_coefficients.items()
-
-        prefix = self.parent().prefix()
-        mons = [ prefix + str(m) for (m, _) in v ]
-        cffs = [ x for (_, x) in v ]
-        x = repr_lincomb(mons, cffs).replace("*1 "," ")
-        if x[len(x)-2:] == "*1":
-            return x[:len(x)-2]
-        else:
-            return x
-
-    def _latex_(self):
-        v = self._monomial_coefficients.items()
-        v.sort()
-        prefix = self.parent().prefix()
-        mons = [ prefix + '_{' + ",".join(map(str, m)) + '}' for (m, _) in v ]
-        cffs = [ x for (_, x) in v ]
-        x = repr_lincomb(mons, cffs, is_latex=True).replace("*1 "," ")
-        if x[len(x)-2:] == "*1":
-            return x[:len(x)-2]
-        else:
-            return x        
-
-    def __cmp__(left, right):
-        """
-        The ordering is the one on the underlying sorted list of (monomial,coefficients) pairs.
-        """
-        v = left._monomial_coefficients.items()
-        v.sort()
-        w = right._monomial_coefficients.items()
-        w.sort()
-        return cmp(v, w)
-
-    def _add_(self, y):
-        A = self.parent()
-        z_elt = dict(self._monomial_coefficients)
-        for m, c in y._monomial_coefficients.iteritems():
-            if z_elt.has_key(m):
-                cm = z_elt[m] + c
-                if cm == 0:
-                    del z_elt[m]
-                else:
-                    z_elt[m] = cm
-            else:
-                z_elt[m] = c
-        z = A(Integer(0))
-        z._monomial_coefficients = z_elt
-        return z
-
-    def _neg_(self):
-        y = self.parent()(0)
-        y_elt = {}
-        for m, c in self._monomial_coefficients.iteritems():
-            y_elt[m] = -c
-        y._monomial_coefficients = y_elt
-        return y
-
-    def _sub_(self, y):
-        A = self.parent()
-        z_elt = dict(self._monomial_coefficients)
-        for m, c in y._monomial_coefficients.iteritems():
-            if z_elt.has_key(m):
-                cm = z_elt[m] - c
-                if cm == 0:
-                    del z_elt[m]
-                else:
-                    z_elt[m] = cm
-            else:
-                z_elt[m] = -c
-        z = A(Integer(0))
-        z._monomial_coefficients = z_elt
-        return z
-                        
-    def _mul_(self, y):
-        return self.parent().multiply(self, y)
-
-    def __pow__(self, n):
-        """
-
-        """
-        if not isinstance(n, (int, Integer)):
-            raise TypeError, "n must be an integer"
-        A = self.parent()
-        z = A(Integer(1))
-        for i in range(n):
-            z *= self
-        return z
-
-    def coefficient(self, m):
-        """
-
-        """        
-        if isinstance(m, partition.Partition_class):
-            return self._monomial_coefficients.get(m, self.parent().base_ring()(0))
-        elif m in partition.Partitions():
-            return self._monomial_coefficients[partition.Partition(m)]
-        else:
-            raise TypeError, "you must specify an element of %s"%self.parent()._combinatorial_class
-
-    def __len__(self):
-        return self.length()
-    
-    def length(self):
-        """
-        EXAMPLES:
-        """
-        return len( filter(lambda x: self._monomial_coefficients[x] != 0, self._monomial_coefficients) )
-
-    def support(self):
-        """
-        EXAMPLES:
-        """
-        v = self._monomial_coefficients.items()
-        mons = [ m for (m, _) in v ]
-        cffs = [ x for (_, x) in v ]
-        return [mons, cffs]
-    
-class CombinatorialAlgebra(Algebra):
-    """
-    """
-    def __init__(self, R, element_class=None):
-        """
-        INPUT:
-            R -- ring
-        """
-        #Make sure R is a ring with unit element
-        if not isinstance(R, Ring):
-            raise TypeError, "Argument R must be a ring."
-        try:
-            z = R(Integer(1))
-        except:
-            raise ValueError, "R must have a unit element"
-
-        #Check to make sure that the user defines the necessary
-        #attributes / methods to make the combinatorial algebra
-        #work
-        required = ['_combinatorial_class','_one',]
-        for r in required:
-            if not hasattr(self, r):
-                raise ValueError, "%s is required"%r
-        if not hasattr(self, '_multiply') and not hasattr(self, '_multiply_basis'):
-            raise ValueError, "either _multiply or _multiply_basis is required"
-
-        #Create a class for the elements of this combinatorial algebra
-        #We need to do this so to distinguish between element of different
-        #combinatorial algebras
-        if element_class is None:
-            if not hasattr(self, '_element_class'):
-                class CAElement(CombinatorialAlgebraElement):
-                    pass
-                self._element_class = CAElement
-        else:
-            self._element_class = element_class
-
-        #Initialize the base structure
-        sage.structure.parent_base.ParentWithBase.__init__(self, R)
-
-    _prefix = ""
-    _name   = "CombinatorialAlgebra -- change me"
-
-    def basis(self):
-        """
-        Returns a list of the basis elements of self.
-        """
-        return map(self, self._combinatorial_class.list())
-    
-    def __call__(self, x):
-        """
-        Coerce x into self.
-        """
-        R = self.base_ring()
-        eclass = self._element_class
-
-        #Coerce ints to Integers
-        if isinstance(x, int):
-            x = Integer(x)
-
-
-        if hasattr(self, '_coerce_start'):
-            try:
-                return self._coerce_start(x)
-            except:
-                pass
-
-        #x is an element of the same type of combinatorial algebra
-        if hasattr(x, 'parent') and x.parent().__class__ is self.__class__:
-            P = x.parent()
-            #same base ring
-            if P is self:
-                return x
-            #different base ring -- coerce the coefficients from into R
-            else:
-                return eclass(self, dict([ (e1,R(e2)) for e1,e2 in x._monomial_coefficients.items()]))
-        #x is an element of the basis combinatorial class
-        elif x in self._combinatorial_class:
-            return eclass(self, {self._combinatorial_class.object_class(x):R(1)})
-        #Coerce elements of the base ring
-        elif x.parent() is R:
-            return eclass(self, {self._combinatorial_class.object_class(self._one):x})
-        #Coerce things that coerce into the base ring
-        elif R.has_coerce_map_from(x.parent()):
-            return eclass(self, {self._combinatorial_class.object_class(self._one):R(x)})
-        else:
-            if hasattr(self, '_coerce_end'):
-                try:
-                    return self._coerce_start(x)
-                except:
-                    pass
-            raise TypeError, "do not know how to make x (= %s) an element of self"%(x)
-
-
-    def _an_element_impl(self):
-        return self._element_class(self, {self._combinatorial_class.object_class(self._one):self.base_ring()(1)})
-
-    def _repr_(self):
-        return self._name + " over %s"%self.base_ring()
-
-    def combintorial_class(self):
-        return self._combinatorial_class
-
-    def _coerce_impl(self, x):
-        try:
-            R = x.parent()
-            if R.__class__ is self.__class__:
-                #Only perform the coercion if we can go from the base
-                #ring of x to the base ring of self
-                if self.base_ring().has_coerce_map_from( R.base_ring() ):
-                    return self(x)
-        except AttributeError:
-            pass
-        
-        # any ring that coerces to the base ring
-        return self._coerce_try(x, [self.base_ring()])
-                                
-    def prefix(self):
-        return self._prefix
-
-    def multiply(self,left,right):
-        A = left.parent()
-        R = A.base_ring()
-        z_elt = {}
-
-        #Do the case where the user specifies how to multiply basis
-        #elements
-        if hasattr(self, '_multiply_basis'):
-            for (left_m, left_c) in left._monomial_coefficients.iteritems():
-                for (right_m, right_c) in right._monomial_coefficients.iteritems():
-                    res = self._multiply_basis(left_m, right_m)
-                    #Handle the case where the user returns a dictionary
-                    #where the keys are the monomials and the values are
-                    #the coefficients
-                    if isinstance(res, dict):
-                        for m in res:
-                            if m in z_elt:
-                                z_elt[ m ] = z_elt[m] + left_c * right_c * res[m]
-                            else:
-                                z_elt[ m ] = left_c * right_c * res[m]
-                    #Otherwise, res is assumed to be an element of the
-                    #object class
-                    else:
-                        m = res
-                        if m  in z_elt:
-                            z_elt[ m ] = z_elt[m] + left_c * right_c
-                        else:
-                            z_elt[ m ] = left_c * right_c
-        #We assume that the user handles the multiplication correctly on
-        #his or her own, and returns a dict with monomials as keys and
-        #coefficients as values
-        else:
-            z_elt = self._multiply(left, right)
-
-        z = A(Integer(0))
-        z._monomial_coefficients = z_elt
-        return z
-
-import partition
-class TestCA(CombinatorialAlgebra):
-    _combinatorial_class = partition.Partitions()
-    _name = "Test Combinatorial Algebra"
-    _one = partition.Partition([])
-    def _multiply_basis(self, left_basis, right_basis):
-        #Append the two lists
-        m = list(left_basis) + list(right_basis)
-        #Sort the new lists
-        m.sort(reverse=True)
-        return partition.Partition(m)
Index: age/combinat/composition.py
===================================================================
--- sage/combinat/composition.py	(revision 6439)
+++ 	(revision )
@@ -1,624 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 sage.combinat.skew_partition
-from combinat import CombinatorialClass, CombinatorialObject
-import __builtin__
-from sage.rings.integer import Integer
-from sage.rings.arith import binomial
-import misc
-
-def Composition(co=None, descents=None, code=None):
-    """
-    Returns a composition object.
-    
-    EXAMPLES:
-      The standard way to create a composition is by specifying it
-      as a list.
-        
-        sage: Composition([3,1,2])
-        [3, 1, 2]
-
-      You can create a composition from a list of its descents.
-        
-        sage: Composition([1, 1, 3, 4, 3]).descents()
-        [0, 1, 4, 8, 11]
-        sage: Composition(descents=[1,0,4,8,11])
-        [1, 1, 3, 4, 3]
-
-      You can also create a composition from its code.
-
-        sage: Composition([4,1,2,3,5]).to_code()
-        [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
-        sage: Composition(code=_)          
-        [4, 1, 2, 3, 5]
-        sage: Composition([3,1,2,3,5]).to_code()
-        [1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
-        sage: Composition(code=_)
-        [3, 1, 2, 3, 5]
-    """
-
-    if descents != None:
-        if isinstance(descents, tuple):
-            return from_descents(descents[0], nps=descents[1])
-        else:
-            return from_descents(descents)
-    elif code != None:
-        return from_code(code)
-    else:
-        if co not in Compositions():
-            raise ValueError, "invalid composition"
-        else:
-            return Composition_class(co)
-
-class Composition_class(CombinatorialObject):
-    def conjugate(self):
-        r"""
-        Returns the conjugate of the composition comp.
-
-        Algorithm from mupad-combinat.
-
-        EXAMPLES:
-            sage: Composition([1, 1, 3, 1, 2, 1, 3]).conjugate()  
-            [1, 1, 3, 3, 1, 3]
-
-        """
-        comp = self
-        if comp == []:
-            return Composition([])
-        n = len(comp)
-        coofcp = [sum(comp[:j])-j+1 for j in range(1,n+1)]
-
-        cocjg = []
-        for i in range(n-1):
-            cocjg += [i+1 for k in range(0, (coofcp[n-i-1]-coofcp[n-i-2]))]
-        cocjg += [n for j in range(coofcp[0])]
-
-        return Composition([cocjg[0]] + [cocjg[i]-cocjg[i-1]+1 for i in range(1,len(cocjg)) ])
-
-
-    def complement(self):
-        """
-        Returns the complement of the composition co.  The complement
-        is the reverse of co's conjugate composition.
-
-        EXAMPLES:
-            sage: Composition([1, 1, 3, 1, 2, 1, 3]).conjugate()
-            [1, 1, 3, 3, 1, 3]
-            sage: Composition([1, 1, 3, 1, 2, 1, 3]).complement()
-            [3, 1, 3, 3, 1, 1]
-
-        """
-        return Composition([element for element in reversed(self.conjugate())])
-
-    def is_finer(self, co2):
-        """
-        Returns True if the composition self is finer than the composition
-        co2; otherwise, it returns False.
-     
-        EXAMPLES:
-            sage: Composition([4,1,2]).is_finer([3,1,3])
-            False
-            sage: Composition([3,1,3]).is_finer([4,1,2])
-            False
-            sage: Composition([1,2,2,1,1,2]).is_finer([5,1,3])
-            True
-            sage: Composition([2,2,2]).is_finer([4,2])
-            True
-        """
-        co1 = self
-        if sum(co1) != sum(co2):
-            #Error: compositions are not of the same size
-            raise ValueError, "compositions self (= %s) and co2 (= %s) must be of the same size"%(self, co2)
-
-
-        sum1 = 0
-        sum2 = 0
-        i1 = 0
-        for i2 in range(len(co2)):
-            sum2 += co2[i2]
-            while sum1 < sum2:
-                sum1 += co1[i1]
-                i1 += 1
-            if sum1 > sum2:
-                return False
-
-        return True
-
-    def refinement(self, co2):
-        """
-        Returns the refinement composition of self and co2.
-
-        EXAMPLES:
-            sage: Composition([1,2,2,1,1,2]).refinement([5,1,3])
-            [3, 1, 2]
-        """
-        co1 = self
-        if sum(co1) != sum(co2):
-            #Error: compositions are not of the same size
-            raise ValueError, "compositions self (= %s) and co2 (= %s) must be of the same size"%(self, co2)
-
-        sum1 = 0
-        sum2 = 0
-        i1 = -1
-        result = []
-        for i2 in range(len(co2)):
-            sum2 += co2[i2]
-            i_res = 0
-            while sum1 < sum2:
-                i1 += 1
-                sum1 += co1[i1]
-                i_res += 1
-
-            if sum1 > sum2:
-                return None
-
-            result.append(i_res)
-
-        return Composition(result)
-
-    def major_index(self):
-        """
-        Returns the major index of the composition co.  The major index is defined
-        as the sum of the descents.
-   
-        EXAMPLES:
-            sage: Composition([1, 1, 3, 1, 2, 1, 3]).major_index()
-            31
-        """
-        co = self
-        lv = len(co)
-        if lv == 1:
-            return 0
-        else:
-            return sum([(lv-(i+1))*co[i] for i in range(lv)])
-
-   
-    def to_code(self):
-        """
-        Returns the code of the composition self.
-
-        EXAMPLES:
-            sage: Composition([4,1,2,3,5]).to_code()
-            [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
-        """
-
-        if self == []:
-            return [0]
-
-        code = []
-        for i in range(len(self)):
-            code += [1] + [0]*(self[i]-1)
-
-        return code 
-
-
-    def descents(self, final_descent=False):
-        """
-        Returns the list of descents of the composition co.
-
-        EXAMPLES:
-            sage: Composition([1, 1, 3, 1, 2, 1, 3]).descents()
-            [0, 1, 4, 5, 7, 8, 11]
-        """
-        s = -1
-        d = []
-        for i in range(len(self)):
-            s += self[i]
-            d += [s]
-        if len(self) != 0 and final_descent:
-            d += [len(self)-1]
-        return d
-
-
-    def peaks(self):
-        """
-        Returns a list of the peaks of the composition self.
-
-        The peaks are the positions i in the compositions such that
-        self[i-1] < self[i] > self[i+1].  Note that len(self)-1 is
-        never a peak.
-
-        EXAMPLES:
-            sage: Composition([1, 1, 3, 1, 2, 1, 3]).peaks()
-            [2, 4]
-
-        """
-        n = sum(self)
-        p = []
-        for i in range(1,len(self)-1):
-            if self[i-1] < self[i] and self[i] > self[i+1]:
-                p += [i]
-
-        return p
-
-    def to_skew_partition(self, overlap=1):
-        """
-        Returns the skew partition obtained from the composition co.
-        The parameter overlap indicates the number of boxes that are
-        covered by boxes of the previous line.
-
-        EXAMPLES:
-            sage: Composition([3,4,1]).to_skew_partition()
-            [[6, 6, 3], [5, 2]]
-            sage: Composition([3,4,1]).to_skew_partition(overlap=0)
-            [[8, 7, 3], [7, 3]]
-
-        """
-        co = self
-        outer = []
-        inner = []
-        sum_outer = -1*overlap
-
-        for k in range(len(self)-1):
-            outer += [ self[k]+sum_outer+overlap  ]
-            sum_outer += self[k]-overlap
-            inner += [ sum_outer + overlap ]
-
-        if self != []:
-            outer += [self[-1]+sum_outer+overlap]
-        else:
-            return [[],[]]
-
-        return sage.combinat.skew_partition.SkewPartition(
-            [ filter(lambda x: x != 0, [l for l in reversed(outer)]),
-              filter(lambda x: x != 0, [l for l in reversed(inner)])])
-    
-
-
-##############################################################
-
-
-def Compositions(n=None, **kwargs):
-    """
-    Returns the combinatorial class of compositions.
-
-    EXAMPLES:
-      If n is not specificied, it returns the combinatorial
-      class of all (non-negative) integer compositions.
-
-        sage: Compositions()
-        Compositions of non-negative integers
-        sage: [] in Compositions()
-        True
-        sage: [2,3,1] in Compositions()
-        True
-        sage: [-2,3,1] in Compositions()
-        False
-
-      If n is specified, it returns the class of compositions
-      of n.
-
-        sage: Compositions(3)
-        Compositions of 3
-        sage: Compositions(3).list()
-        [[1, 1, 1], [1, 2], [2, 1], [3]]
-        sage: Compositions(3).count()
-        4
-
-      In addition, the following constaints can be put on the
-      compositions: length, min_part, max_part, min_length,
-      max_length, min_slope, max_slope, inner, and outer.
-      For example,
-
-        sage: Compositions(3, length=2).list()
-        [[1, 2], [2, 1]]
-        sage: Compositions(4, max_slope=0).list()
-        [[1, 1, 1, 1], [2, 1, 1], [2, 2], [3, 1], [4]]
-    """
-    if n == None:
-        return Compositions_all()
-    else:
-        if kwargs:
-            return Compositions_constraints(n, **kwargs)
-        else:
-            return Compositions_n(n)
-
-class Compositions_all(CombinatorialClass):
-    def __init__(self):
-        """
-        TESTS:
-            sage: C = Compositions()
-            sage: C == loads(dumps(C))
-            True
-        """
-        pass
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Compositions())
-            'Compositions of non-negative integers'
-        """
-        return "Compositions of non-negative integers"
-
-    object_class = Composition_class
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: [2,1,3] in Compositions()
-            True
-            sage: [] in Compositions()
-            True
-            sage: [-2,-1] in Compositions()
-            False
-            sage: [0,0] in Compositions()
-            True
-        """
-        if isinstance(x, Composition_class):
-            return True
-        elif isinstance(x, __builtin__.list):
-            for i in range(len(x)):
-                if not isinstance(x[i], (int, Integer)):
-                    return False
-                if x[i] < 0:
-                    return False
-            return True
-        else:
-            return False
-
-    def list(self):
-        """
-        TESTS:
-            sage: Compositions().list()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError
-        """
-        raise NotImplementedError
-
-class Compositions_n(CombinatorialClass):
-    def __init__(self, n):
-        """
-        TESTS:
-            sage: C = Compositions(3)
-            sage: C == loads(dumps(C))
-            True
-        """
-        self.n = n
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Compositions(3))
-            'Compositions of 3'
-        """
-        return "Compositions of %s"%self.n
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: [2,1,3] in Compositions(6)
-            True
-            sage: [2,1,2] in Compositions(6)
-            False
-            sage: [] in Compositions(0)
-            True
-            sage: [0] in Compositions(0)
-            True
-        """
-        return x in Compositions() and sum(x) == self.n
-
-    def count(self):
-        """
-        TESTS:
-            sage: Compositions(3).count()
-            4
-            sage: Compositions(0).count()
-            1
-        """
-        if self.n >= 1:
-            return 2**(self.n-1)
-        elif self.n == 0:
-            return 1
-        else:
-            return 0
-
-    def list(self):
-        """
-        TESTS:
-            sage: Compositions(4).list()
-            [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]]
-            sage: Compositions(0).list()
-            [[]]
-        """
-        if self.n == 0:
-            return [Composition_class([])]
-        
-        result = []
-        for i in range(1,self.n+1):
-            result += map(lambda x: [i]+x[:], Compositions_n(self.n-i).list())
-
-        return [Composition_class(r) for r in result]
-
-
-class Compositions_constraints(CombinatorialClass):
-    object_class = Composition_class
-
-    def __init__(self, n, **kwargs):
-        """
-            sage: C = Compositions(4, length=2)
-            sage: C == loads(dumps(C))
-            True
-        """
-        self.n = n
-        self.constraints = kwargs
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Compositions(6, min_part=2, length=3))
-            'Compositions of 6 with constraints length=3, min_part=2'
-        """
-        return "Compositions of %s with constraints %s"%(self.n, ", ".join( ["%s=%s"%(key, self.constraints[key]) for key in sorted(self.constraints.keys())] ))
-    
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: [2, 1] in Compositions(3, length=2)
-            True
-            sage: [2,1,2] in Compositions(5, min_part=1)
-            True
-            sage: [2,1,2] in Compositions(5, min_part=2)
-            False
-        """
-        return x in Compositions() and sum(x) == self.n and misc.check_integer_list_constraints(x, singleton=True, **self.constraints)
-    
-
-    def count(self):
-        """
-         EXAMPLES:
-            sage: Compositions(4, length=2).count()
-            3
-            sage: Compositions(4, min_length=2).count()
-            7
-            sage: Compositions(4, max_length=2).count()
-            4
-            sage: Compositions(4, max_part=2).count()
-            5
-            sage: Compositions(4, min_part=2).count()
-            2
-            sage: Compositions(4, outer=[3,1,2]).count()
-            3       
-        """
-        if len(self.constraints) == 1 and 'length' in self.constraints:
-            if self.n >= 1:
-                return binomial(self.n-1, self.constraints['length'] - 1)
-            elif self.n == 0:
-                if self.constraints['length'] == 0:
-                    return 1
-                else:
-                    return 0
-            else:
-                return 0
-        return len(self.list())
-
-
-
-    def list(self):
-        """
-        Returns a list of all the compositions of n.
-
-        EXAMPLES:
-            sage: Compositions(4, length=2).list()
-            [[1, 3], [2, 2], [3, 1]]
-            sage: Compositions(4, min_length=2).list()
-            [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1]]
-            sage: Compositions(4, max_length=2).list()
-            [[1, 3], [2, 2], [3, 1], [4]]
-            sage: Compositions(4, max_part=2).list()
-            [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [2, 1, 1], [2, 2]]
-            sage: Compositions(4, min_part=2).list()
-            [[2, 2], [4]]
-            sage: Compositions(4, outer=[3,1,2]).list()
-            [[1, 1, 2], [2, 1, 1], [3, 1]]
-            sage: Compositions(4, outer=[1,'inf',1]).list()
-            [[1, 2, 1], [1, 3]]
-            sage: Compositions(4, inner=[1,1,1]).list()
-            [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [2, 1, 1]]
-            sage: Compositions(4, min_slope=0).list()
-            [[1, 1, 1, 1], [1, 1, 2], [1, 3], [2, 2], [4]]
-            sage: Compositions(4, min_slope=-1, max_slope=1).list()
-            [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [2, 1, 1], [2, 2], [4]]
-            sage: Compositions(5, max_slope=1, min_slope=-2, min_length=2, max_length=4).list()
-            [[1, 1, 1, 2],
-             [1, 1, 2, 1],
-             [1, 2, 1, 1],
-             [1, 2, 2],
-             [2, 1, 1, 1],
-             [2, 1, 2],
-             [2, 2, 1],
-             [2, 3],
-             [3, 1, 1],
-             [3, 2]]
-            sage: Compositions(5, max_slope=1, min_slope=-2, min_length=2, max_length=4, outer=[2,5,2]).list()
-            [[1, 2, 2], [2, 1, 2], [2, 2, 1], [2, 3]]
-
-        """
-        n = self.n
-
-        if n == 0:
-            return [Composition_class([])]
-
-        result = []
-        for i in range(1,n+1):
-            result += map(lambda x: [i]+x[:], Compositions_constraints(n-i).list())
-
-        if self.constraints:
-            result = misc.check_integer_list_constraints(result, **self.constraints)
-
-        result = [Composition_class(r) for r in result]
-
-        return result
-
-
-
-
-def from_descents(descents, nps=None):
-    """
-    Returns a composition from the list of descents.
-
-    EXAMPLES:
-        sage: Composition([1, 1, 3, 4, 3]).descents()
-        [0, 1, 4, 8, 11]
-        sage: sage.combinat.composition.from_descents([1,0,4,8],12)
-        [1, 1, 3, 4, 3]
-        sage: sage.combinat.composition.from_descents([1,0,4,8,11])
-        [1, 1, 3, 4, 3]
-    """
-
-    d = [x+1 for x in descents]
-    d.sort()
-
-    if d == []:
-        if nps == 0:
-            return []
-        else:
-            return [nps]
-
-    if nps != None:
-        if nps < max(d):
-            #Error: d is not included in [1,...,nps-1]
-            return None
-        elif nps > max(d):
-            d.append(nps)
-
-    co = [d[0]]
-    for i in range(len(d)-1):
-        co += [ d[i+1]-d[i] ]
-
-    return Composition(co)
-
-def from_code(code):
-    """
-    Return the composition from its code.
-
-    EXAMPLES:
-    sage: Composition([4,1,2,3,5]).to_code()
-    [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
-    sage: composition.from_code(_)          
-    [4, 1, 2, 3, 5]
-    sage: Composition([3,1,2,3,5]).to_code()
-    [1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
-    sage: composition.from_code(_)          
-    [3, 1, 2, 3, 5]
-
-    """
-    if code == [0]:
-        return []
-
-    L = filter(lambda x: code[x]==1, range(len(code))) #the positions of the letter 1
-    return Composition([L[i]-L[i-1] for i in range(1, len(L))] + [len(code)-L[-1]])
-
Index: age/combinat/composition_signed.py
===================================================================
--- sage/combinat/composition_signed.py	(revision 6439)
+++ 	(revision )
@@ -1,134 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 combinat import CombinatorialObject, CombinatorialClass
-import composition
-import cartesian_product
-import itertools
-from sage.rings.all import binomial, Integer
-import __builtin__
-
-def SignedCompositions(n):
-    """
-    Returns the combinatorial class of signed compositions of
-    n.
-
-    EXAMPLES:
-        sage: SC3 = SignedCompositions(3); SC3
-        Signed compositions of 3
-        sage: SC3.count()
-        18
-        sage: len(SC3.list())
-        18
-        sage: SC3.first()
-        [1, 1, 1]
-        sage: SC3.last()
-        [-3]
-        sage: SC3.random() #random
-        [-1, -2]
-        sage: SC3.list()
-        [[1, 1, 1],
-         [1, 1, -1],
-         [1, -1, 1],
-         [1, -1, -1],
-         [-1, 1, 1],
-         [-1, 1, -1],
-         [-1, -1, 1],
-         [-1, -1, -1],
-         [1, 2],
-         [1, -2],
-         [-1, 2],
-         [-1, -2],
-         [2, 1],
-         [2, -1],
-         [-2, 1],
-         [-2, -1],
-         [3],
-         [-3]]
-    """
-    return SignedCompositions_n(n)
-
-class SignedCompositions_n(CombinatorialClass):
-    def __init__(self, n):
-        """
-        TESTS:
-            sage: SC3 = SignedCompositions(3)
-            sage: SC3 == loads(dumps(SC3))
-            True
-        """
-        self.n = n
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SignedCompositions(3))
-            'Signed compositions of 3'
-        """
-        return "Signed compositions of %s"%self.n
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: [] in SignedCompositions(0)
-            True
-            sage: [0] in SignedCompositions(0)
-            False
-            sage: [2,1,3] in SignedCompositions(6)
-            True
-            sage: [-2, 1, -3] in SignedCompositions(6)
-            True
-        """
-        if x == []:
-            return True
-        
-        if isinstance(x, __builtin__.list):
-            for i in range(len(x)):
-                if not isinstance(x[i], (int, Integer)):
-                    return False
-                if x[i] == 0:
-                    return False
-                return True
-        else:
-            return False
-
-        return sum([abs(i) for i in x]) == self.n
-        
-    def count(self):
-        """
-        TESTS:
-            sage: SC4 = SignedCompositions(4)
-            sage: SC4.count() == len(SC4.list())
-            True
-            sage: SignedCompositions(3).count()
-            18
-        """
-        return sum([ binomial(self.n-1, i-1)*2**(i) for i in range(1, self.n+1)])
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: SignedCompositions(0).list()   #indirect test
-            [[]]
-            sage: SignedCompositions(1).list()   #indirect test
-            [[1], [-1]]
-            sage: SignedCompositions(2).list()   #indirect test
-            [[1, 1], [1, -1], [-1, 1], [-1, -1], [2], [-2]]
-        """
-        for comp in composition.Compositions(self.n):
-            l = len(comp)
-            a = [[1,-1] for i in range(l)]
-            for sign in cartesian_product.CartesianProduct(*a):
-                yield [ sign[i]*comp[i] for i in range(l)]
-
Index: age/combinat/dyck_word.py
===================================================================
--- sage/combinat/dyck_word.py	(revision 6439)
+++ 	(revision )
@@ -1,591 +1,0 @@
-import sage.combinat.misc as misc
-from combinat import catalan_number
-import __builtin__
-from sage.sets.set import Set
-from combinat import CombinatorialClass, CombinatorialObject
-import tableau
-
-open_symbol = 1
-close_symbol = 0
-
-    
-def DyckWord(dw=None, noncrossing_partition=None):
-    """
-    Returns a Dyck word object
-
-    EXAMPLES:
-        sage: dw = DyckWord([1, 0, 1, 0]); dw
-        [1, 0, 1, 0]
-        sage: print dw
-        ()()
-        sage: print dw.height()
-        1
-        sage: dw.to_noncrossing_partition()
-        [[1], [2]]
-
-        sage: DyckWord('()()')
-        [1, 0, 1, 0]
-
-        sage: DyckWord(noncrossing_partition=[[1],[2]])
-        [1, 0, 1, 0]
-    """
-    global open_symbol, close_symbol
-    
-    if noncrossing_partition != None:
-        return from_noncrossing_partition(noncrossing_partition)
-    
-    elif isinstance(dw, str):
-        def replace(x):
-            if x == '(':
-                return open_symbol
-            elif x == ')':
-                return close_symbol
-            else:
-                raise ValueError, "we should only have open and close symbols, not %s"%x
-        l = map(replace, dw)
-    else:
-        l = dw
-        
-    if l in DyckWords() or is_a_prefix(l): 
-        return DyckWord_class(l)
-    else:
-        raise ValueError, "invalid Dyck word"
-
-class DyckWord_class(CombinatorialObject):
-    def __str__(self):
-        """
-        Returns a string consisting of matched parenteses corresponding to
-        the Dyck word.
-        
-        EXAMPLES:
-            sage: print DyckWord([1, 0, 1, 0])
-            ()()
-            sage: print DyckWord([1, 1, 0, 0])
-            (())
-        """
-        global open_symbol, close_symbol
-        def replace(x):
-            if x == open_symbol:
-                return '('
-            elif x == close_symbol:
-                return ')'
-            else:
-                raise ValueError, "we should only have open and close symbols, not %s"%x
-
-        return "".join(map(replace, [x for x in self]))
-
-
-    def size(self):
-        """
-        Returns the size of the Dyck word, which is the number
-        of opening parentheses in the Dyck word.
-
-        EXAMPLES:
-            sage: DyckWord([1, 0, 1, 0]).size()
-            2
-            sage: DyckWord([1, 0, 1, 1, 0]).size()
-            3
-        """
-        global open_symbol
-        return len(filter(lambda x: x == open_symbol, self))
-
-    def height(self):
-        """
-        Returns the height of the Dyck word.
-        
-        EXAMPLES:
-            sage: DyckWord([]).height()
-            0
-            sage: DyckWord([1,0]).height()
-            1
-            sage: DyckWord([1, 1, 0, 0]).height()
-            2
-            sage: DyckWord([1, 1, 0, 1, 0]).height()
-            2
-            sage: DyckWord([1, 1, 0, 0, 1, 0]).height()
-            2
-            sage: DyckWord([1, 0, 1, 0]).height()
-            1
-            sage: DyckWord([1, 1, 0, 0, 1, 1, 1, 0, 0, 0]).height()
-            3
-        """
-        global open_symbol, close_symbol
-        
-        height = 0
-        height_max = 0
-        for letter in self:
-            if letter == open_symbol:
-                height += 1
-                height_max = max(height, height_max)
-            elif letter == close_symbol:
-                height -= 1
-        return height_max
-
-    def associated_parenthesis(self, pos):
-        """
-        EXAMPLES:
-            sage: DyckWord([1, 0]).associated_parenthesis(0)
-            1
-            sage: DyckWord([1, 0, 1, 0]).associated_parenthesis(0)
-            1
-            sage: DyckWord([1, 0, 1, 0]).associated_parenthesis(1)
-            0
-            sage: DyckWord([1, 0, 1, 0]).associated_parenthesis(2)
-            3
-            sage: DyckWord([1, 0, 1, 0]).associated_parenthesis(3)
-            2
-            sage: DyckWord([1, 1, 0]).associated_parenthesis(1)
-            2
-            sage: DyckWord([1, 1]).associated_parenthesis(0)
-        """
-        global open_symbol, close_symbol
-        d = 0
-        height = 0
-        if pos >= len(self):
-            raise ValueError, "invalid index"
-        
-        if self[pos] == open_symbol:
-            d += 1
-            height += 1
-        elif self[pos] == close_symbol:
-            d -= 1
-            height -= 1
-        else:
-            raise ValueError, "unknown symbol %s"%self[pos-1]
-
-        while height != 0:
-            pos += d
-            if pos < 0 or pos >= len(self):
-                return None
-            if self[pos] == open_symbol:
-                height += 1
-            elif self[pos] == close_symbol:
-                height -= 1
-
-        return pos
-            
-    def to_noncrossing_partition(self):
-        """
-        Bijection of Biane from Dyck words to non crossing partitions
-        Thanks to Mathieu Dutour for describing the bijection.
-
-        EXAMPLES:
-            sage: DyckWord([1, 0]).to_noncrossing_partition()
-            [[1]]
-            sage: DyckWord([1, 1, 0, 0]).to_noncrossing_partition()
-            [[1, 2]]
-            sage: DyckWord([1, 1, 1, 0, 0, 0]).to_noncrossing_partition()
-            [[1, 2, 3]]
-            sage: DyckWord([1, 0, 1, 0, 1, 0]).to_noncrossing_partition()
-            [[1], [2], [3]]
-            sage: DyckWord([1, 1, 0, 1, 0, 0]).to_noncrossing_partition()
-            [[2], [1, 3]]
-        """
-        global open_symbol, close_symbol
-        
-        partition = [] 
-        stack = []
-        i = 0
-        p = 1
-
-        #Invariants:
-        # - self[i] = 0
-        # - p is the number of opening parens at position i
-
-        while i < len(self):
-            stack.append(p)
-            j = i + 1
-            while j < len(self) and self[j] == close_symbol:
-                j += 1
-
-            #Now j points to the next 1 or past the end of self
-            nz = j - (i+1) # the number of )'s between i and j
-            if nz > 0:
-                # Remove the nz last elements of stack and
-                # make a new part in partition
-                if nz > len(stack):
-                    raise ValueError, "incorrect dyck word"
-
-                partition.append( stack[-nz:] )
-
-                stack = stack[: -nz]
-            i = j
-            p += 1
-            
-        if len(stack) > 0:
-            raise ValueError, "incorrect dyck word"
-
-        return partition
-
-    def to_ordered_tree(self):
-        """
-        TESTS:
-            sage: DyckWord([1, 1, 0, 0]).to_triangulation()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError: TODO
-        """
-        raise NotImplementedError, "TODO"
-
-    def to_triangulation(self):
-        """
-        TESTS:
-            sage: DyckWord([1, 1, 0, 0]).to_triangulation()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError: TODO
-        """
-        raise NotImplementedError, "TODO"
-
-    def peaks(self):
-        """
-        EXAMPLES:
-            sage: DyckWord([1, 0, 1, 0]).peaks()
-            [0, 2]
-            sage: DyckWord([1, 1, 0, 0]).peaks()
-            [1]
-        """
-        global open_symbol, close_symbol
-        return filter(lambda i: self[i] == open_symbol and self[i+1] == close_symbol, range(len(self)-1))
-
-    def to_tableau(self):
-        """
-        EXAMPLES:
-            sage: DyckWord([]).to_tableau()
-            []
-            sage: DyckWord([1, 0]).to_tableau()
-            [[2], [1]]
-            sage: DyckWord([1, 1, 0, 0]).to_tableau()
-            [[3, 4], [1, 2]]
-            sage: DyckWord([1, 0, 1, 0]).to_tableau()
-            [[2, 4], [1, 3]]
-            sage: DyckWord([1]).to_tableau()
-            [[1]]
-            sage: DyckWord([1, 0, 1]).to_tableau()
-            [[2], [1, 3]]
-        """
-        global open_symbol, close_symbol
-        open_positions = []
-        close_positions = []
-
-        for i in range(len(self)):
-            if self[i] == open_symbol:
-                open_positions.append(i+1)
-            else:
-                close_positions.append(i+1)
-        return filter(lambda x: x != [],  [ close_positions, open_positions ])
-
-
-def DyckWords(k1=None, k2=None):
-    """
-    Returns the combinatorial class of Dyck words.
-
-    EXAMPLES:
-      If neither k1 nor k2 are specified, then it returns
-      the combinatorial class of all Dyck words.
-      
-        sage: DW = DyckWords(); DW
-        Dyck words
-        sage: [] in DW
-        True
-        sage: [1, 0, 1, 0] in DW
-        True
-        sage: [1, 1, 0] in DW
-        False
-
-      If just k1 is specified, then it returns the combinatorial
-      class of Dyck words with k1 opening parentheses and k1
-      closing parentheses.
-        sage: DW2 = DyckWords(2); DW2
-        Dyck words with 2 opening parentheses and 2 closing parentheses
-        sage: DW2.first()
-        [1, 1, 0, 0]
-        sage: DW2.last()
-        [1, 0, 1, 0]
-        sage: DW2.count()
-        2
-
-      If k2 is specified in addition to k1, then it returns
-      the combinatorial class of Dyck words with k1 opening
-      parentheses and k2 closing parentheses.
-        sage: DW32 = DyckWords(3,2); DW32
-        Dyck words with 3 opening parentheses and 2 closing parentheses
-        sage: DW32.list()
-        [[1, 1, 1, 0, 0],
-         [1, 1, 0, 1, 0],
-         [1, 1, 0, 0, 1],
-         [1, 0, 1, 1, 0],
-         [1, 0, 1, 0, 1]]
-    """
-    if k1 == None and k2 == None:
-        return DyckWords_all()
-    else:
-        if k2 != None and k1 < k2:
-            raise ValueError, "k1 (= %s) must be >= k2 (= %s)"%(k1, k2)
-        if k2 == None:
-            return DyckWords_size(k1, k1)
-        else:
-            return DyckWords_size(k1, k2)
-
-class DyckWords_all(CombinatorialClass):
-    def __init__(self):
-        """
-        TESTS:
-            sage: DW = DyckWords()
-            sage: DW == loads(dumps(DW))
-            True
-        """
-        pass
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(DyckWords())
-            'Dyck words'
-        """
-        return "Dyck words"
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: [] in DyckWords()
-            True
-            sage: [1] in DyckWords()
-            False
-            sage: [0] in DyckWords()
-            False 
-            sage: [1, 0] in DyckWords()
-            True
-        """
-        global open_symbol, close_symbol
-        if isinstance(x, DyckWord_class):
-            return True
-
-        if not isinstance(x, __builtin__.list):
-            return False
-
-        if len(x) % 2 != 0:
-            return False
-
-        return is_a(x)
-
-    def list(self):
-        """
-        TESTS:
-            sage: DyckWords().list()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError
-        """
-        raise NotImplementedError
-
-class DyckWords_size(CombinatorialClass):
-    def __init__(self, k1, k2=None):
-        """
-        TESTS:
-            sage: DW4 = DyckWords(4)
-            sage: DW4 == loads(dumps(DW4))
-            True
-            sage: DW42 = DyckWords(4,2)
-            sage: DW42 == loads(dumps(DW42))
-            True
-            
-        """
-        self.k1 = k1
-        self.k2 = k2
-
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(DyckWords(4))
-            'Dyck words with 4 opening parentheses and 4 closing parentheses'
-        """
-        return "Dyck words with %s opening parentheses and %s closing parentheses"%(self.k1, self.k2)
-    
-    def count(self):
-        """
-        Returns the number of Dyck words of size n, i.e. the n-th Catalan number.
-        
-        EXAMPLES:
-            sage: DyckWords(4).count()
-            14
-            sage: ns = range(9)
-            sage: dws = [DyckWords(n) for n in ns]
-            sage: all([ dw.count() == len(dw.list()) for dw in dws])
-            True
-        """
-        if self.k2 == self.k1:
-            return catalan_number(self.k1)
-        else:
-            return len(self.list())
-
-    def __contains__(self, x):
-        """
-        EXAMPLES:
-             sage: [1, 0] in DyckWords(1)
-             True
-             sage: [1, 0] in DyckWords(2)
-             False
-             sage: [1, 1, 0, 0] in DyckWords(2)
-             True
-             sage: [1, 0, 0, 1] in DyckWords(2)
-             False
-             sage: [1, 0, 0, 1] in DyckWords(2,2)
-             False
-             sage: [1, 0, 1, 0] in DyckWords(2,2)
-             True
-             sage: [1, 0, 1, 0, 1] in DyckWords(3,2)
-             True
-             sage: [1, 0, 1, 1, 0] in DyckWords(3,2)
-             True
-             sage: [1, 0, 1, 1] in DyckWords(3,1)
-             True
-        """
-        return is_a(x, self.k1, self.k2)
-
-    def list(self):
-        """
-        Returns a list of all the Dyck words of size n.
-
-        EXAMPLES:
-            sage: DyckWords(0).list()
-            [[]]
-            sage: DyckWords(1).list()
-            [[1, 0]]
-            sage: DyckWords(2).list()
-            [[1, 1, 0, 0], [1, 0, 1, 0]]
-        """
-        global open_symbol, close_symbol
-        k1 = self.k1
-        k2 = self.k2
-
-        if k1 == 0:
-            return [ DyckWord([]) ]
-        if k2 == 0:
-            return [ DyckWord([ open_symbol for x in range(k1) ]) ]
-        if k1 == 1:
-            return [ DyckWord([ open_symbol, close_symbol ]) ]
-
-        dycks = []
-        if k1 > k2:
-            dycks +=  map( lambda x: [open_symbol] + __builtin__.list(x), DyckWords(k1-1, k2) )
-
-        for i in range(k2):
-            for d1 in DyckWords(i,i):
-                for d2 in DyckWords(k1-i-1, k2-i-1):
-                    dycks.append( [open_symbol] + __builtin__.list(d1) + [close_symbol] + __builtin__.list(d2))
-
-        dycks.sort()
-        dycks.reverse()
-        return map(lambda x: DyckWord(x), dycks)
-
-
-
-
-
-def is_a_prefix(obj, k1 = None, k2 = None):
-    """
-
-    If k1 is specificied, then the object must have exactly k1 open
-    symbols.  If k2 is also specified, then obj must have exactly
-    k2 close symbols.
-
-    EXAMPLES:
-    
-    """
-    global open_symbol, close_symbol
-    
-    if k1 != None and k2 == None:
-        k2 = k1
-    if k1 != None and k1 < k2:
-        raise ValueError, "k1 (= %s) must be >= k2 (= %s)"%(k1, k2)
-
-
-    n_opens = 0
-    n_closes = 0
-
-    for p in obj:
-        if p == open_symbol:
-            n_opens += 1
-        elif p == close_symbol:
-            n_closes += 1
-        else:
-            return False
-
-        if n_opens < n_closes:
-            return False
-
-        if k1 == None and k2 == None:
-            return True
-        elif k2 == None:
-            return n_opens == k1
-        else:
-            return n_opens == k1 and n_closes == k2
-
-
-def is_a(obj, k1 = None, k2 = None):
-    """
-    """
-    global open_symbol, close_symbol
-    
-    if k1 != None and k2 == None:
-        k2 = k1
-    if k1 != None and k1 < k2:
-        raise ValueError, "k1 (= %s) must be >= k2 (= %s)"%(k1, k2)
-
-
-    n_opens = 0
-    n_closes = 0
-
-    for p in obj:
-        if p == open_symbol:
-            n_opens += 1
-        elif p == close_symbol:
-            n_closes += 1
-        else:
-            return False
-
-        if n_opens < n_closes:
-            return False
-
-    if k1 == None and k2 == None:
-        return n_opens == n_closes
-    elif k2 == None:
-        return n_opens == n_closes and n_opens == k1
-    else:
-        return n_opens == k1 and n_closes == k2
-
-def from_noncrossing_partition(ncp):
-    """
-    TESTS:
-        sage: DyckWord(noncrossing_partition=[[1,2]])
-        [1, 1, 0, 0]
-        sage: DyckWord(noncrossing_partition=[[1],[2]])
-        [1, 0, 1, 0]
-
-        sage: dws = DyckWords(5).list()
-        sage: ncps = map( lambda x: x.to_noncrossing_partition(), dws)
-        sage: dws2 = map( lambda x: DyckWord(noncrossing_partition=x), ncps)
-        sage: dws == dws2
-        True
-    """
-    global open_symbol, close_symbol
-    
-    l = [ 0 ] * int( sum( [ len(v) for v in ncp ] ) )
-    for v in ncp:
-        l[v[-1]-1] = len(v)
-
-    res = []
-    for i in l:
-        res += [ open_symbol ] + [close_symbol]*int(i)
-    return DyckWord(res)
-
-def from_ordered_tree(tree):
-    """
-    TESTS:
-        sage: sage.combinat.dyck_word.from_ordered_tree(1)
-        Traceback (most recent call last):
-        ...
-        NotImplementedError: TODO
-    """
-    raise NotImplementedError, "TODO"
Index: age/combinat/generator.py
===================================================================
--- sage/combinat/generator.py	(revision 6439)
+++ 	(revision )
@@ -1,94 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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/
-#*****************************************************************************
-
-def concat(gens):
-    r"""
-    Returns a generator that is the concatenation
-    of the generators in the list.
-
-    EXAMPLES:
-        sage: list(sage.combinat.generator.concat([[1,2,3],[4,5,6]]))
-        [1, 2, 3, 4, 5, 6]
-    """
-
-    for gen in gens:
-        for element in gen:
-            yield element
-
-
-def map(f, gen):
-    """
-    Returns a generator that returns f(g) for
-    g in gen.
-
-    EXAMPLES:
-        sage: f = lambda x: x*2
-        sage: list(sage.combinat.generator.map(f,[4,5,6]))
-        [8, 10, 12]
-    """
-    for element in gen:
-        yield f(element)
-
-def element(element, n = 1):
-    """
-    Returns a generator that yield a single element
-    n times.
-
-    EXAMPLES:
-        sage: list(sage.combinat.generator.element(1))
-        [1]
-        sage: list(sage.combinat.generator.element(1, n=3))
-        [1, 1, 1]
-    """
-    for i in range(n):
-        yield element
-
-def select(f, gen):
-    """
-    Returns a generator for all the elements g of gen
-    such that f(g) is True.
-
-    EXAMPLES:
-        sage: f = lambda x: x % 2 == 0
-        sage: list(sage.combinat.generator.select(f,range(7)))
-        [0, 2, 4, 6]
-    """
-    for element in gen:
-        if f(element):
-            yield element
-
-
-def successor(initial, succ):
-    """
-    Given an initial value and a successor function,
-    yeild the initial value and each following successor.
-    The generator will continue to generate values until
-    the successor function yields None.
-
-    EXAMPLES:
-        sage: def f(x):
-        ...       if x < 10:
-        ...           return x+1
-        sage: list(sage.combinat.generator.successor(0,f))
-        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-    """
-    yield initial
-
-    s = succ(initial)
-    while s:
-        yield s
-        s = succ(s)
-
-        
Index: age/combinat/integer_list.py
===================================================================
--- sage/combinat/integer_list.py	(revision 6439)
+++ 	(revision )
@@ -1,559 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 generator
-from sage.calculus.calculus import Function_floor
-from sage.rings.arith import binomial
-from sage.rings.infinity import PlusInfinity
-import __builtin__
-
-flr = Function_floor()
-infinity = PlusInfinity()
-
-def first(n, min_length, max_length, floor, ceiling, min_slope, max_slope):
-    """
-    Returns the lexicographically smallest valid composition of n
-    satisfying the conditions.
-
-    Preconditions:
-    //  - minslope < maxslope
-    //  - floor and ceiling need to satisfy the slope constraints
-    //    e.g. be obtained from comp2floor or comp2ceil
-    //  - floor must be below ceiling to ensure the existence a
-    //    valid composition
-
-    EXAMPLES:
-
-
-    TESTS:
-        sage: import sage.combinat.integer_list as integer_list
-        sage: f = lambda l: lambda i: l[i-1]
-        sage: f([0,1,2,3,4,5])(1)
-        0
-        sage: integer_list.first(12, 4, 4, f([0,0,0,0]), f([4,4,4,4]), -1, 1)
-        [4, 3, 3, 2]
-        sage: integer_list.first(36, 9, 9, f([3,3,3,2,1,1,0,0,0]), f([7,6,5,5,5,5,5,4,4]), -1, 1)
-        [7, 6, 5, 5, 4, 3, 3, 2, 1]
-        sage: integer_list.first(25, 9, 9, f([3,3,3,2,1,1,0,0,0]), f([7,6,5,5,5,5,5,4,4]), -2, 1)
-        [7, 6, 5, 4, 2, 1, 0, 0, 0]
-        sage: integer_list.first(36, 9, 9, f([3,3,3,2,1,4,2,0,0]), f([7,6,5,5,5,5,5,4,4]), -2, 1)
-        [7, 6, 5, 5, 5, 4, 3, 1, 0]
-
-    """
-
-    #Increase minl until n <= sum([ceiling(i) for i in range(min_length)])
-    #This may run forever!
-    N = sum([ceiling(i) for i in range(1,min_length+1)])
-    while N < n:
-        min_length += 1
-        if min_length > max_length:
-            return None
-            raise ValueError, "min length > max length"
-
-        if ceiling(min_length) == 0 and max_slope <= 0:
-            return None
-            raise ValueError, "N will never increase again"
-
-        N += ceiling(min_length)
-
-
-    #This is the place where it's required that floor(i)
-    #respects the floor conditions.
-    n -= sum([floor(i) for i in range(1, min_length+1)])
-    if n < 0:
-        return None
-        raise ValueError
-
-    #Now we know that we can build the composition inside
-    #the "tube" [1 ... min_length] * [floor, ceiling]
-
-    if min_slope == -infinity:
-        #Easy case: min_slope == -infinity
-        result = []
-        i = min_length
-        for i in range(1,min_length+1):
-            if n <= ceiling(i) - floor(i):
-                result.append(floor(i) + n)
-                break
-            else:
-                result.append(ceiling(i))
-                n -= ceiling(i) - floor(i)
-
-        result += [floor(j) for j in range(i+1,min_length+1)]
-        return result
-
-    else:
-        if n == 0 and min_length == 0:
-            return []
-
-        low_x = 1
-        low_y = floor(1)
-        high_x = 1
-        high_y = floor(1)
-
-        while n > 0:
-            #invariant after each iteration of the loop:
-            #[low_x, low_y] is the coordinate of the rightmost point of the
-            #current diagonal s.t. floor(low_x) < low_y
-            low_y += 1
-            while low_x < min_length and low_y+min_slope > floor(low_x + 1):
-                low_x += 1
-                low_y += min_slope
-
-            high_y += 1
-            while high_y > ceiling(high_x):
-                high_x += 1
-                high_y += min_slope
-
-            n -= low_x - high_x + 1
-
-        #print "lx, ly, hw, hy, n", low_x, low_y, high_x, high_y, n
-        #print (high_x-1 - 1 + 1)  + (n + 1 - 0 + 1) + ( low_x-high_x - n + 1) + (min_length - (low_x + 1) +1)
-        result = []
-        result += [ ceiling(j) for j in range(1,high_x)] 
-        result += [ high_y + min_slope*i - 1 for i in range(0, -n) ] 
-        result += [ high_y + min_slope*i for i in range(-n, low_x-high_x+1)]
-        result += [ floor(j) for j in range(low_x+1,min_length+1) ]
-
-        return result
-
-
-def lower_regular(comp, min_slope, max_slope):
-    """
-    Returns the uppest regular composition below comp
-
-    TESTS:
-        sage: import sage.combinat.integer_list as integer_list
-        sage: integer_list.lower_regular([4,2,6], -1, 1)
-        [3, 2, 3]
-        sage: integer_list.lower_regular([4,2,6], -1, infinity)
-        [3, 2, 6]
-        sage: integer_list.lower_regular([1,4,2], -1, 1)
-        [1, 2, 2]
-        sage: integer_list.lower_regular([4,2,6,3,7], -2, 1)
-        [4, 2, 3, 3, 4]
-        sage: integer_list.lower_regular([4,2,infinity,3,7], -2, 1)
-        [4, 2, 3, 3, 4]
-        sage: integer_list.lower_regular([1, infinity, 2], -1, 1)
-        [1, 2, 2]
-        sage: integer_list.lower_regular([infinity, 4, 2], -1, 1)
-        [4, 3, 2]
-    """
-
-    new_comp = comp[:]
-    for i in range(1, len(new_comp)):
-        new_comp[i] = min(new_comp[i], new_comp[i-1] + max_slope)
-
-    for i in reversed(range(len(new_comp)-1)):
-        new_comp[i] = min( new_comp[i], new_comp[i+1] - min_slope)
-
-    return new_comp
-
-def rightmost_pivot(comp, min_length, max_length, floor, ceiling, min_slope, max_slope):
-    """
-
-    TESTS:
-        sage: import sage.combinat.integer_list as integer_list
-        sage: f = lambda l: lambda i: l[i-1]
-        sage: integer_list.rightmost_pivot([7,6,5,5,4,3,3,2,1], 9, 9, f([3,3,3,2,1,1,0,0,0]), f([7,6,5,5,5,5,5,4,4]), -1, 0)
-        [7, 2]
-        sage: integer_list.rightmost_pivot([7,6,5,5,4,3,3,2,1], 9, 9,f([3,3,3,2,1,1,0,0,0]), f([7,6,5,5,5,5,5,4,4]), -2, 0)
-        [7, 1]
-        sage: integer_list.rightmost_pivot([7,6,5,5,4,3,3,2,1], 9, 9,f([3,3,3,2,1,1,0,0,0]), f([7,6,5,5,5,5,5,4,4]), -2, 4)
-        [8, 1]
-        sage: integer_list.rightmost_pivot([7,6,5,5,4,3,3,2,1], 9, 9,f([3,3,3,2,1,1,0,0,0]), f([7,6,5,5,5,5,5,4,4]), -2, 1)
-        [8, 1]
-        sage: integer_list.rightmost_pivot([7,6,5,5,5,5,5,4,4], 9, 9,f([3,3,3,2,1,1,0,0,0]), f([7,6,5,5,5,5,5,4,4]), -2, 1)
-        sage: integer_list.rightmost_pivot([3,3,3,2,1,1,0,0,0], 9, 9,f([3,3,3,2,1,1,0,0,0]), f([7,6,5,5,5,5,5,4,4]), -2, 1)
-        sage: g = lambda x: lambda i: x
-        sage: integer_list.rightmost_pivot([1],1,1,g(0),g(2),-10, 10)
-        sage: integer_list.rightmost_pivot([1,2],2,2,g(0),g(2),-10, 10)
-        sage: integer_list.rightmost_pivot([1,2],2,2,g(1),g(2), -10, 10)
-        sage: integer_list.rightmost_pivot([1,2],2,3,g(1),g(2), -10, 10)
-        [2, 1]
-        sage: integer_list.rightmost_pivot([2,2],2,3,g(2),g(2),-10, 10)
-        sage: integer_list.rightmost_pivot([2,3],2,3,g(2),g(2),-10,+10)
-        sage: integer_list.rightmost_pivot([3,2],2,3,g(2),g(2),-10,+10)
-        sage: integer_list.rightmost_pivot([3,3],2,3,g(2),g(2),-10,+10)
-        [1, 2]
-        sage: integer_list.rightmost_pivot([6],1,3,g(0),g(6),-1,0)
-        [1, 0]
-        sage: integer_list.rightmost_pivot([6],1,3,g(0),g(6),-2,0)
-        [1, 0]
-        sage: integer_list.rightmost_pivot([7,9,8,7],1,5,g(0),g(10),-1,10)
-        [2, 6]
-        sage: integer_list.rightmost_pivot([7,9,8,7],1,5,g(5),g(10),-10,10)
-        [3, 5]
-        sage: integer_list.rightmost_pivot([7,9,8,7],1,5,g(5),g(10),-1,10)
-        [2, 6]
-        sage: integer_list.rightmost_pivot([7,9,8,7],1,5,g(4),g(10),-2,10)
-        [3, 7]
-        sage: integer_list.rightmost_pivot([9,8,7],1,4,g(4),g(10),-2,0)
-        [1, 4]
-        sage: integer_list.rightmost_pivot([1,3],1,5,lambda i: i,g(10),-10,10)
-        sage: integer_list.rightmost_pivot([1,4],1,5,lambda i: i,g(10),-10,10)
-        sage: integer_list.rightmost_pivot([2,4],1,5,lambda i: i,g(10),-10,10)
-        [1, 1]
-
-
-    """
-    
-    y = len(comp) + 1
-    while y <= max_length:
-        if ceiling(y) > 0:
-            break
-        if maxSlope <= 0:
-            y = max_length + 1
-            break
-        y += 1
-
-    x = len(comp)
-    if x == 0:
-        return None
-
-    ceilingx_x = comp[x-1]-1
-    floorx_x = floor(x)
-    if x > 1:
-        floorx_x = max(floorx_x, comp[x-2]+min_slope)
-
-    F = comp[x-1] - floorx_x
-    G = ceilingx_x - comp[x-1] #this is -1
-
-    highX = x
-    lowX  = x
-  
-    while not (ceilingx_x >= floorx_x and
-               (G >= 0 or
-               ( y < max_length +1 and
-                 F - max(floor(y), floorx_x + (y-x)*min_slope) >= 0 and
-                 G + min(ceiling(y), ceilingx_x + (y-x)*max_slope) >= 0 ))):
-
-        if x == 1:
-            return None
-
-        x -= 1
-
-        old_ceilingx_x = ceilingx_x
-        oldfloorx_x    = floorx_x
-        ceilingx_x = comp[x-1] - 1
-        floorx_x   = floor(x)
-        if x > 1:
-            floorx_x = max(floorx_x, comp[x-2]+min_slope)
-
-        min_slope_lowX  = min_slope*(lowX - x)
-        max_slope_highX = max_slope*(highX - x)
-
-
-        #Update G
-        if max_slope == infinity:
-            #In this case, we have
-            #  -- ceiling_x(i) = ceiling(i) for i > x
-            #  --G >= 0 or G = -1
-            G += ceiling(x+1)-comp[x]
-        else:
-            G += (highX - x)*( (comp[x-1]+max_slope) - comp[x]) - 1
-            temp = (ceilingx_x + max_slope_highX) - ceiling(highX)
-            while highX > x and ( temp >= 0 ):
-                G  -= temp
-                highX -= 1
-                max_slope_highX = max_slope*(highX-x)
-                temp = (ceilingx_x + max_slope_highX) - ceiling(highX)
-
-        if G >= 0 and comp[x-1] > floorx_x:
-            #By case 1, x is at the rightmost pivot position
-            break
-
-        #Update F
-        if y < max_length+1:
-            F += comp[x-1] - floorx_x
-            if min_slope != -infinity:
-                F += (lowX - x) * (oldfloorx_x - (floorx_x + min_slope))
-                temp = floor(lowX) - (floorx_x + min_slope_lowX)
-                while lowX > x and temp >= 0:
-                    F -= temp
-                    lowX -= 1
-                    min_slope_lowX = min_slope*(lowX-x)
-                    temp = floor(lowX) - (floorx_x + min_slope_lowX)
-
-    return [x, floorx_x]
-
-def next(comp, min_length, max_length, floor, ceiling, min_slope, max_slope):
-    """
-    Returns the next integer list after comp that satisfies the contraints.        
-    """
-
-    x = rightmost_pivot( comp, min_length, max_length, floor, ceiling, min_slope, max_slope)
-    if x == None:
-        return None
-    [x, low] = x
-    high = comp[x-1]-1
-
-##     // Build wrappers around floor and ceiling to take into
-##     // account the new constraints on the value of compo[x].
-##     //
-##     // Efficiency note: they are not wrapped more than once, since
-##     // the method Next calls first, but not the converse.
-
-    if min_slope == -infinity:
-        new_floor = lambda i: floor(x+(i-1))
-    else:
-        new_floor = lambda i: max(floor(x+(i-1)), low+(i-1)*min_slope)
-
-    if max_slope == infinity:
-        def new_ceiling(i):
-            if i == 1:
-                return comp[x-1] - 1
-            else:
-                return ceiling(x+(i-1))
-    else:
-        new_ceiling = lambda i: min(ceiling(x+(i-1)), high+(i-1)*max_slope)
-
-
-    res = []
-    res += comp[:x-1]
-    res += first(sum(comp[x-1:]), max(min_length-x+1, 0), max_length-x+1,
-                 new_floor, new_ceiling, min_slope, max_slope)
-    return res
-
-                                  
-         
-
-
-def iterator(n, min_length, max_length, floor, ceiling, min_slope, max_slope):
-    """
-
-    """
-
-    succ = lambda x: next(x, min_length, max_length, floor, ceiling, min_slope, max_slope)
-
-    #Handle the case where n is a list of integers
-    if isinstance(n, __builtin__.list):
-        iterators = [iterator(i, min_length, max_length, floor, ceiling, min_slope, max_slope) for i in range(n[0], min(n[1]+1,upper_bound(min_length, max_length, floor, ceiling, min_slope, max_slope)))]
-        
-        return generator.concat(iterators)
-    else:
-        f =  first(n, min_length, max_length, floor, ceiling, min_slope, max_slope)
-        if f == None:
-            return generator.element(None, 0)
-        return generator.successor(f, succ)
-
-def list(n, min_length, max_length, floor, ceiling, min_slope, max_slope):
-    """
-
-    EXAMPLES:
-        sage: import sage.combinat.integer_list as integer_list
-        sage: g = lambda x: lambda i: x
-        sage: integer_list.list(0,0,infinity,g(1),g(infinity),0,infinity)
-        [[]]
-        sage: integer_list.list(0,0,infinity,g(1),g(infinity),0,0)
-        [[]]
-        sage: integer_list.list(0, 0, 0, g(1), g(infinity), 0, 0)
-        [[]]
-        sage: integer_list.list(0, 0, 0, g(0), g(infinity), 0, 0)
-        [[]]
-        sage: integer_list.list(0, 0, infinity, g(1), g(infinity), 0, infinity)
-        [[]]
-        sage: integer_list.list(1, 0, infinity, g(1), g(infinity), 0, infinity)
-        [[1]]
-        sage: integer_list.list(0, 1, infinity, g(1), g(infinity), 0, infinity)
-        []
-        sage: integer_list.list(0, 1, infinity, g(0), g(infinity), 0, infinity)
-        [[0]]
-        sage: integer_list.list(3, 0, 2, g(0), g(infinity), -infinity, infinity)
-        [[3], [2, 1], [1, 2], [0, 3]]
-        sage: partitions = (0, infinity, g(0), g(infinity), -infinity, 0)
-        sage: partitions_min_2 = (0, infinity, g(2), g(infinity), -infinity, 0)
-        sage: compositions = (0, infinity, g(1), g(infinity), -infinity, infinity)
-        sage: integer_vectors = lambda l: (l, l, g(0), g(infinity), -infinity, infinity)
-        sage: lower_monomials = lambda c: (len(c), len(c), g(0), lambda i: c[i], -infinity, infinity)
-        sage: upper_monomials = lambda c: (len(c), len(c), g(0), lambda i: c[i], -infinity, infinity)
-        sage: constraints = (0, infinity, g(1), g(infinity), -1, 0)
-        sage: integer_list.list(6, *partitions)
-        [[6],
-         [5, 1],
-         [4, 2],
-         [4, 1, 1],
-         [3, 3],
-         [3, 2, 1],
-         [3, 1, 1, 1],
-         [2, 2, 2],
-         [2, 2, 1, 1],
-         [2, 1, 1, 1, 1],
-         [1, 1, 1, 1, 1, 1]]
-        sage: integer_list.list(6, *constraints)
-        [[6],
-         [3, 3],
-         [3, 2, 1],
-         [2, 2, 2],
-         [2, 2, 1, 1],
-         [2, 1, 1, 1, 1],
-         [1, 1, 1, 1, 1, 1]]
-        sage: integer_list.list(1, *partitions_min_2)
-        []
-        sage: integer_list.list(2, *partitions_min_2)
-        [[2]]
-        sage: integer_list.list(3, *partitions_min_2)
-        [[3]]
-        sage: integer_list.list(4, *partitions_min_2)
-        [[4], [2, 2]]
-        sage: integer_list.list(5, *partitions_min_2)
-        [[5], [3, 2]]
-        sage: integer_list.list(6, *partitions_min_2)
-        [[6], [4, 2], [3, 3], [2, 2, 2]]
-        sage: integer_list.list(7, *partitions_min_2)
-        [[7], [5, 2], [4, 3], [3, 2, 2]]
-        sage: integer_list.list(9, *partitions_min_2)
-        [[9], [7, 2], [6, 3], [5, 4], [5, 2, 2], [4, 3, 2], [3, 3, 3], [3, 2, 2, 2]]
-        sage: integer_list.list(10, *partitions_min_2)
-        [[10],
-         [8, 2],
-         [7, 3],
-         [6, 4],
-         [6, 2, 2],
-         [5, 5],
-         [5, 3, 2],
-         [4, 4, 2],
-         [4, 3, 3],
-         [4, 2, 2, 2],
-         [3, 3, 2, 2],
-         [2, 2, 2, 2, 2]]
-        sage: integer_list.list(4, *compositions)
-        [[4], [3, 1], [2, 2], [2, 1, 1], [1, 3], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]
-    """
-    return __builtin__.list(iterator(n, min_length, max_length, floor, ceiling, min_slope, max_slope))
-
-def upper_regular(comp, min_slope, max_slope):
-    """
-    Returns the uppest regular composition above comp.
-
-    TESTS:
-        sage: import sage.combinat.integer_list as integer_list
-        sage: integer_list.upper_regular([4,2,6],-1,1)
-        [4, 5, 6]
-        sage: integer_list.upper_regular([4,2,6],-2, 1)
-        [4, 5, 6]
-        sage: integer_list.upper_regular([4,2,6,3,7],-2, 1)
-        [4, 5, 6, 6, 7]
-        sage: integer_list.upper_regular([4,2,6,1], -2, 1)
-        [4, 5, 6, 4]
-    """
-
-    new_comp = comp[:]
-    for i in range(1, len(new_comp)):
-        new_comp[i] = max(new_comp[i], new_comp[i-1] + min_slope)
-
-    for i in reversed(range(len(new_comp)-1)):
-        new_comp[i] = max( new_comp[i], new_comp[i+1] - max_slope)
-
-    return new_comp
-
-def comp2floor(f, min_slope, max_slope):
-    """
-    Given a composition, returns the lowest regular function N->N above
-    it
-    """
-
-    if len(f) == 0:
-        def res(i):
-            return 0
-        return res
-
-
-    floor = upper_regular(f, min_slope, max_slope)
-
-    def res(i):
-        if i < len(floor):
-            return floor[i]
-        else:
-            return max(0, floor[-1]-(i-len(floor))*min_slope)
-
-    return res
-
-
-        
-    
-def comp2ceil(c, min_slope, max_slope):
-    """
-    Given a composition, returns the lowest regular function N->N below
-    it
-    """
-
-    if len(c) == 0:
-        def res(i):
-            return 0
-        return res
-
-
-    ceil = lower_regular(c, min_slope, max_slope)
-
-    def res(i):
-        if i < len(ceil):
-            return ceil[i]
-        else:
-            return max(0, ceil[-1]-(i-len(ceil))*min_slope)
-
-    return res
-
-
-def upper_bound(min_length, max_length, floor, ceiling, min_slope, max_slope):
-    """
-    Compute a coarse upper bound on the size of a vector satisfying
-    the constraints.
-
-    TESTS:
-        sage: import sage.combinat.integer_list as integer_list
-        sage: f = lambda x: lambda i: x
-        sage: integer_list.upper_bound(0,4,f(0), f(1),-infinity,infinity)
-        4
-        sage: integer_list.upper_bound(0, infinity, f(0), f(1), -infinity, infinity)
-        +Infinity
-        sage: integer_list.upper_bound(0, infinity, f(0), f(1), -infinity, -1)
-        1
-        sage: integer_list.upper_bound(0, infinity, f(0), f(5), -infinity, -1)
-        15
-        sage: integer_list.upper_bound(0, infinity, f(0), f(5), -infinity, -2)
-        9
-
-    """
-
-    if max_length < infinity:
-        return sum( [ ceiling(j) for j in range(max_length)] )
-    elif max_slope < 0 and ceiling(1) < infinity:
-        maxl = flr(-ceiling(1)/max_slope)
-        return ceiling(1)*(maxl+1) + binomial(maxl+1,2)*max_slope
-    #FIXME: only checking the first 10000 values, but that should generally
-    #be enough
-    elif [ceiling(j) for j in range(10000)] == [0 for x in range(10000)]:
-        return 0
-    else:
-        return infinity
-    
-
-
-def is_a(comp, min_length, max_length, floor, ceiling, min_slope, max_slope):
-    """
-    """
-    if len(comp) < min_length or len(comp) > max_length:
-        return False
-    for i in range(len(comp)):
-        if comp[i] < floor(i+1):
-            return False
-        if comp[i] > ceiling(i+1):
-            return False
-    for i in range(len(comp)-1):
-        slope = comp[i+1] - comp[i]
-        if slope < min_slope or slope > max_slope:
-            return False
-    return True
Index: age/combinat/integer_vector.py
===================================================================
--- sage/combinat/integer_vector.py	(revision 6439)
+++ 	(revision )
@@ -1,509 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 combinat import CombinatorialClass, CombinatorialObject
-from __builtin__ import list as builtinlist
-from sage.rings.integer import Integer
-from sage.rings.arith import binomial
-import misc
-from sage.rings.infinity import PlusInfinity
-import integer_list
-import cartesian_product
-
-infinity = PlusInfinity()
-def list2func(l, default=None):
-    """
-    Given a list l, return a function that takes in a value
-    i and return l[i-1].  If default != None, then the function
-    will return the default value for out of range i's.
-
-    EXAMPLES:
-        sage: f = sage.combinat.integer_vector.list2func([1,2,3])
-        sage: f(1)
-        1
-        sage: f(2)
-        2
-        sage: f(3)
-        3
-        sage: f(4)
-        Traceback (most recent call last):
-        ...
-        IndexError: list index out of range
-
-        sage: f = sage.combinat.integer_vector.list2func([1,2,3], 0)
-        sage: f(3)
-        3
-        sage: f(4)
-        0
-    """
-    if default is None:
-        return lambda i: l[i-1]
-    else:
-        def f(i):
-            try:
-                return l[i-1]
-            except IndexError:
-                return default
-        return f
-       
-def constant_func(i):
-    """
-    Returns the constant function i.
-
-    EXAMPLES:
-        sage: f = sage.combinat.integer_vector.constant_func(3)
-        sage: f(-1)
-        3
-        sage: f('asf')
-        3
-    """
-    return lambda x: i
-
-def IntegerVectors(n=None, k=None, **kwargs):
-    """
-    Returns the combinatorial class of integer vectors.
-
-    EXAMPLES:
-      If n is not specified, it returns the class of all
-      integer vectors.
-      
-        sage: IntegerVectors()
-        Integer vectors
-        sage: [] in IntegerVectors()
-        True
-        sage: [1,2,1] in IntegerVectors()
-        True
-        sage: [1, 0, 0] in IntegerVectors()
-        True
-
-      If n is specified, then it returns the class of all
-      integer vectors which sum to n.
-      
-        sage: IV3 = IntegerVectors(3); IV3
-        Integer vectors that sum to 3
-
-      Note that trailing zeros are ignored so that [3, 0]
-      does not show up in the following list (since [3] does)
-      
-        sage: IntegerVectors(3, max_length=2).list()
-        [[3], [2, 1], [1, 2], [0, 3]]
-
-      If n and k are both specified, then it returns the class
-      of integer vectors that sum to n and are of length k.
-
-        sage: IV53 = IntegerVectors(5,3); IV53
-        Integer vectors of length 3 that sum to 5
-        sage: IV53.count()
-        21
-        sage: IV53.first()
-        [5, 0, 0]
-        sage: IV53.last()
-        [0, 0, 5]
-        sage: IV53.random() #random
-        [0, 1, 4]
-
-    """
-    if n == None:
-        return IntegerVectors_all()
-    elif k == None:
-        return IntegerVectors_nconstraints(n,kwargs)
-    else:
-        if isinstance(k, builtinlist):
-            return IntegerVectors_nnondescents(n,k)
-        else:
-            return IntegerVectors_nkconstraints(n,k,kwargs)
-
-
-class IntegerVectors_all(CombinatorialClass):
-    def __repr__(self):
-        return "Integer vectors"
-    
-    def __contains__(self, x):
-        """
-        EXAMPLES:
-            sage: [] in IntegerVectors()
-            True
-            sage: [3,2,2,1] in IntegerVectors()
-            True
-  
-        """
-        if not isinstance(x, builtinlist):
-            return False
-        for i in x:
-            if not isinstance(i, (int, Integer)):
-                return False
-            if i < 0:
-                return False
-
-        return True
-
-    def list(self):
-        raise NotImplementedError
-
-    def count(self):
-        return infinity
-
-class IntegerVectors_nkconstraints(CombinatorialClass):
-    def __init__(self, n, k, constraints):
-        """
-
-        """
-        self.n = n
-        self.k = k
-        self.constraints = constraints
-
-        #n, min_length, max_length, floor, ceiling, min_slope, max_slope
-        if k == -1:
-            min_length = constraints.get('min_length', 0)
-            max_length = constraints.get('max_length', infinity)
-        else:
-            min_length = k
-            max_length = k
-        min_part = constraints.get('min_part', 0)
-        max_part = constraints.get('max_part', infinity)
-        min_slope = constraints.get('min_slope', -infinity)
-        max_slope = constraints.get('max_slope', infinity)
-        if 'outer' in self.constraints:
-            ceiling = list2func( map(lambda i: min(max_part, i), self.constraints['outer']), default=max_part )
-        else:
-            ceiling = constant_func(max_part)
-
-        if 'inner' in self.constraints:
-            floor = list2func( map(lambda i: max(min_part, i), self.constraints['outer']), default=min_part )
-        else:
-            floor = constant_func(min_part)
-
-
-        self._parameters = (min_length, max_length, floor, ceiling, min_slope, max_slope)
-
-    def __repr__(self):
-        if self.constraints:
-            return "Integer vectors of length %s that sum to %s with constraints %s"%(self.k, self.n, ", ".join( ["%s=%s"%(key, self.constraints[key]) for key in sorted(self.constraints.keys())] ))
-        else:
-            return "Integer vectors of length %s that sum to %s"%(self.k, self.n)
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: [0] in IntegerVectors(0)
-            True
-            sage: [0] in IntegerVectors(0, 1)
-            True
-            sage: [] in IntegerVectors(0, 0)
-            True
-            sage: [] in IntegerVectors(0, 1)
-            False
-            sage: [] in IntegerVectors(1, 0)
-            False
-            sage: [3] in IntegerVectors(3)
-            True
-            sage: [3] in IntegerVectors(2,1)
-            False
-            sage: [3] in IntegerVectors(2)
-            False
-            sage: [3] in IntegerVectors(3,1)
-            True
-            sage: [3,2,2,1] in IntegerVectors(9)
-            False
-            sage: [3,2,2,1] in IntegerVectors(9,5)
-            False            
-            sage: [3,2,2,1] in IntegerVectors(8)
-            True
-            sage: [3,2,2,1] in IntegerVectors(8,5)
-            False
-            sage: [3,2,2,1] in IntegerVectors(8,4)
-            True
-            sage: [3,2,2,1] in IntegerVectors(8,4, min_part = 1)
-            True
-            sage: [3,2,2,1] in IntegerVectors(8,4, min_part = 2)
-            False
-        """
-        if x not in IntegerVectors():
-            return False
-
-        if sum(x) != self.n:
-            return False
-
-        if len(x) != self.k:
-            return False
-
-        if self.constraints:
-            if not misc.check_integer_list_constraints(x, singleton=True, **self.constraints):
-                return False
-
-        return True
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: IntegerVectors(0,0).count()
-            1
-            sage: IntegerVectors(1,0).count()
-            0
-            sage: IntegerVectors(2,2).count()
-            3
-            sage: IntegerVectors(3,3).count()
-            10
-            sage: IntegerVectors(-1,0).count()
-            0
-            sage: IntegerVectors(-1,2).count()
-            0
-            sage: IntegerVectors(3,3, min_part=1).count()
-            1
-            sage: IntegerVectors(5,3, min_part=1).count()
-            6
-            sage: IntegerVectors(13, 4, min_part=2, max_part=4).count()
-            16
-        """
-        if not self.constraints:
-            if self.n >= 0:
-                return binomial(self.n+self.k-1,self.n)
-            else:
-                return 0
-        else:
-            if len(self.constraints) == 1 and 'max_part' in self.constraints and self.constraints['max_part'] != infinity:
-                m = self.constraints['max_part']
-                if m >= self.n:
-                    return binomial(self.n+self.k-1,self.n)
-                else: #do by inclusion / exclusion on the number
-                      #i of parts greater than m
-                    return sum( [(-1)**i * binomial(self.n+self.k-1-i*(m+1), self.k-1)*binomial(self.k,i) for i in range(0, self.n/(m+1)+1)])
-            else:
-                return len(self.list())
-
-    def first(self):
-        """
-        TESTS:
-           
-        """
-        return integer_list.first(self.n, *self._parameters)
-    
-    def next(self, x):
-        """
-        TESTS:
-        """
-        return integer_list.next(x, *self._parameters)
-
-    def iterator(self):
-        """
-
-        TESTS:
-            sage: IntegerVectors(0,0).list()
-            [[]]
-            sage: IntegerVectors(1,0).list()
-            []
-            sage: IntegerVectors(0,1).list()
-            [[0]]
-            sage: IntegerVectors(2,2).list()
-            [[2, 0], [1, 1], [0, 2]]
-            sage: IntegerVectors(-1,0).list()
-            []
-            sage: IntegerVectors(-1,2).list()
-            []
-
-            
-            sage: IntegerVectors(-1, 0, min_part = 1).list()
-            []
-            sage: IntegerVectors(-1, 2, min_part = 1).list()
-            []
-            sage: IntegerVectors(0, 0, min_part=1).list()
-            [[]]
-            sage: IntegerVectors(3, 0, min_part=1).list()
-            []
-            sage: IntegerVectors(0, 1, min_part=1).list()
-            []
-            sage: IntegerVectors(2, 2, min_part=1).list()
-            [[1, 1]]
-            sage: IntegerVectors(2, 3, min_part=1).list()
-            []
-            sage: IntegerVectors(4, 2, min_part=1).list()
-            [[3, 1], [2, 2], [1, 3]]
-
-            sage: IntegerVectors(0, 3, outer=[0,0,0]).list()
-            [[0, 0, 0]]
-            sage: IntegerVectors(1, 3, outer=[0,0,0]).list()
-            []
-            sage: IntegerVectors(2, 3, outer=[0,2,0]).list()
-            [[0, 2, 0]]
-            sage: IntegerVectors(2, 3, outer=[1,2,1]).list()
-            [[1, 1, 0], [1, 0, 1], [0, 2, 0], [0, 1, 1]]
-            sage: IntegerVectors(2, 3, outer=[1,1,1]).list()
-            [[1, 1, 0], [1, 0, 1], [0, 1, 1]]
-            sage: IntegerVectors(2, 5, outer=[1,1,1,1,1]).list()
-            [[1, 1, 0, 0, 0],
-             [1, 0, 1, 0, 0],
-             [1, 0, 0, 1, 0],
-             [1, 0, 0, 0, 1],
-             [0, 1, 1, 0, 0],
-             [0, 1, 0, 1, 0],
-             [0, 1, 0, 0, 1],
-             [0, 0, 1, 1, 0],
-             [0, 0, 1, 0, 1],
-             [0, 0, 0, 1, 1]]
-
-            sage: iv = [ IntegerVectors(n,k) for n in range(-2, 7) for k in range(7) ]
-            sage: all(map(lambda x: x.count() == len(x.list()), iv))
-            True
-            sage: essai = [[1,1,1], [2,5,6], [6,5,2]]
-            sage: iv = [ IntegerVectors(x[0], x[1], max_part = x[2]-1) for x in essai ]
-            sage: all(map(lambda x: x.count() == len(x.list()), iv))
-            True
-                        
-        """
-        return integer_list.iterator(self.n, *self._parameters)
-
-class IntegerVectors_nconstraints(IntegerVectors_nkconstraints):
-    def __init__(self, n, constraints):
-        """
-        TESTS:
-            #sage: IV = IntegerVectors(3)
-            #sage: IV == loads(dumps(IV))
-            #True
-            #sage: IV = IntegerVectors(3, max_length=2)
-            #sage: IV == loads(dumps(IV))
-            #True
-        """
-        IntegerVectors_nkconstraints.__init__(self, n, -1, constraints)
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(IntegerVectors(3))
-            'Integer vectors that sum to 3'
-            sage: repr(IntegerVectors(3, max_length=2))
-            'Integer vectors that sum to 3 with constraints max_length=2'
-        """
-        if self.constraints:
-            return "Integer vectors that sum to %s with constraints %s"%(self.n,", ".join( ["%s=%s"%(key, self.constraints[key]) for key in sorted(self.constraints.keys())] ))
-        else:
-            return "Integer vectors that sum to %s"%(self.n,)
-
-    def __contains__(self, x):
-        """
-        EXAMPLES:
-            sage: [0,3,0,1,2] in IntegerVectors(6)
-            True
-            sage: [0,3,0,1,2] in IntegerVectors(6, max_length=3)
-            False
-        """
-        if self.constraints:
-            return x in IntegerVectors_all() and misc.check_integer_list_constraints(x, singleton=True, **self.constraints)
-        else:
-            return x in IntegerVectors_all() and sum(x) == self.n
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: IntegerVectors(3).count()
-            +Infinity
-        """
-        return infinity
-
-    def list(self):
-        """
-        EXAMPLES:
-            sage: IntegerVectors(3, max_length=2).list()
-            [[3], [2, 1], [1, 2], [0, 3]]
-            sage: IntegerVectors(3).list()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError: infinite list
-        """
-        if 'max_length' not in self.constraints:
-            raise NotImplementedError, "infinite list"
-        else:
-            return list(self.iterator())
-
-
-class IntegerVectors_nnondescents(CombinatorialClass):
-    r"""
-    The combinatorial class of integer vectors v graded by two parameters:
-     - n: the sum of the parts of v
-     - comp: the non descents composition of v
-    
-    In other words: the length of v equals c[1]+...+c[k], and v is
-    descreasing in the consecutive blocs of length c[1], ..., c[k]
-    
-    Those are the integer vectors of sum n which are lexicographically
-    maximal (for the natural left->right reading) in their orbit by the
-    young subgroup S_{c_1} x \dots x S_{c_k}.  In particular, they form
-    a set of orbit representative of integer vectors w.r.t. this young
-    subgroup.
-    """
-    def __init__(self, n, comp):
-        self.n = n
-        self.comp = comp
-
-    def __repr__(self):
-        return "Integer vectors of %s with non-descents composition %s"%(self.n, self.comp)
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: IntegerVectors(0, []).list()
-            [[]]
-            sage: IntegerVectors(5, []).list()
-            []
-            sage: IntegerVectors(0, [1]).list()
-            [[0]]
-            sage: IntegerVectors(4, [1]).list()
-            [[4]]
-            sage: IntegerVectors(4, [2]).list()
-            [[4, 0], [3, 1], [2, 2]]
-            sage: IntegerVectors(4, [2,2]).list()
-             [[4, 0, 0, 0],
-             [3, 0, 1, 0],
-             [2, 0, 2, 0],
-             [2, 0, 1, 1],
-             [1, 0, 3, 0],
-             [1, 0, 2, 1],
-             [0, 0, 4, 0],
-             [0, 0, 3, 1],
-             [0, 0, 2, 2]]
-            sage: IntegerVectors(5, [1,1,1]).list()
-            [[5, 0, 0],
-             [4, 1, 0],
-             [4, 0, 1],
-             [3, 2, 0],
-             [3, 1, 1],
-             [3, 0, 2],
-             [2, 3, 0],
-             [2, 2, 1],
-             [2, 1, 2],
-             [2, 0, 3],
-             [1, 4, 0],
-             [1, 3, 1],
-             [1, 2, 2],
-             [1, 1, 3],
-             [1, 0, 4],
-             [0, 5, 0],
-             [0, 4, 1],
-             [0, 3, 2],
-             [0, 2, 3],
-             [0, 1, 4],
-             [0, 0, 5]]
-            sage: IntegerVectors(0, [2,3]).list()
-            [[0, 0, 0, 0, 0]]
-
-         """
-        for iv in IntegerVectors(self.n, len(self.comp)):
-            blocks = [ IntegerVectors(iv[i], self.comp[i], max_slope=0).iterator() for i in range(len(self.comp))]
-            for parts in cartesian_product.CartesianProduct(*blocks):
-                res = []
-                for part in parts:
-                    res += part
-                yield res
-
-    
Index: age/combinat/integer_vector_weighted.py
===================================================================
--- sage/combinat/integer_vector_weighted.py	(revision 6439)
+++ 	(revision )
@@ -1,144 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 combinat import CombinatorialClass, CombinatorialObject
-from __builtin__ import list as builtinlist
-from sage.rings.integer import Integer
-import word
-from permutation import Permutation_class
-
-def WeightedIntegerVectors(n, weight):
-    """
-    Returns the combinatorial class of integer vectors of n
-    weighted by weight.
-
-    EXAMPLES:
-        sage: WeightedIntegerVectors(8, [1,1,2])
-        Integer vectors of 8 weighted by [1, 1, 2]
-        sage: WeightedIntegerVectors(8, [1,1,2]).first()
-        [0, 0, 4]
-        sage: WeightedIntegerVectors(8, [1,1,2]).last()
-        [8, 0, 0]
-        sage: WeightedIntegerVectors(8, [1,1,2]).count()
-        25
-        sage: WeightedIntegerVectors(8, [1,1,2]).random() #random
-        [2, 0, 3]
-    """
-    return WeightedIntegerVectors_nweight(n, weight)
-
-class WeightedIntegerVectors_nweight(CombinatorialClass):
-    def __init__(self, n, weight):
-        """
-        TESTS:
-            sage: WIV = WeightedIntegerVectors(8, [1,1,2])
-            sage: WIV == loads(dumps(WIV))
-            True
-        """
-        self.n = n
-        self.weight = weight
-        
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(WeightedIntegerVectors(8, [1,1,2]))
-            'Integer vectors of 8 weighted by [1, 1, 2]'
-        """
-        return "Integer vectors of %s weighted by %s"%(self.n, self.weight)
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: [] in WeightedIntegerVectors(0, [])
-            True
-            sage: [] in WeightedIntegerVectors(1, [])
-            False
-            sage: [3,0,0] in WeightedIntegerVectors(6, [2,1,1])
-            True
-            sage: [1] in WeightedIntegerVectors(1, [1])
-            True
-            sage: [1] in WeightedIntegerVectors(2, [2])
-            True
-            sage: [2] in WeightedIntegerVectors(4, [2])
-            True
-            sage: [2, 0] in WeightedIntegerVectors(4, [2, 2])
-            True
-            sage: [2, 1] in WeightedIntegerVectors(4, [2, 2])
-            False
-            sage: [2, 1] in WeightedIntegerVectors(6, [2, 2])
-            True
-            sage: [2, 1, 0] in WeightedIntegerVectors(6, [2, 2])
-            False
-            sage: [0] in WeightedIntegerVectors(0, [])
-            False
-        """
-        if not isinstance(x, builtinlist):
-            return False
-        if len(self.weight) != len(x):
-            return False
-        s = 0
-        for i in range(len(x)):
-            if not isinstance(x[i], (int, Integer)):
-                return False
-            s += x[i]*self.weight[i]
-        if s != self.n:
-            return False
-
-        return True
-
-    def list(self):
-        """
-        TESTS:
-            sage: WeightedIntegerVectors(7, [2,2]).list()
-            []
-            sage: WeightedIntegerVectors(3, [2,1,1]).list()
-            [[1, 0, 1], [1, 1, 0], [0, 0, 3], [0, 1, 2], [0, 2, 1], [0, 3, 0]]
-
-            sage: ivw = [ WeightedIntegerVectors(k, [1,1,1]) for k in range(11) ]
-            sage: iv  = [ IntegerVectors(k, 3) for k in range(11) ]
-            sage: all( [ sorted(iv[k].list()) == sorted(ivw[k].list()) for k in range(11) ] )
-            True
-
-            sage: ivw = [ WeightedIntegerVectors(k, [2,3,7]) for k in range(11) ]
-            sage: all( [ i.count() == len(i.list()) for i in ivw] )
-            True
-        """
-
-        if len(self.weight) == 0:
-            if n == 0:
-                return [[]]
-            else:
-                return []
-
-        perm = word.standard(self.weight)
-        l = [x for x in sorted(self.weight)]
-
-        def recfun(n, l):
-            result = []
-            w = l[-1]
-            l = l[:-1]
-            if l == []:
-                d = int(n) / int(w)
-                if n%w == 0:
-                    return [[d]]
-                else:
-                    return [] #bad branch...
-
-            for d in range(int(n)/int(w), -1, -1):
-                result += map( lambda x: x + [d], recfun(n-d*w, l) )
-
-            return result
-
-        return map( lambda x: Permutation_class(perm)._left_to_right_multiply_on_right(Permutation_class(x)), recfun(self.n,l) )
-            
Index: age/combinat/lyndon_word.py
===================================================================
--- sage/combinat/lyndon_word.py	(revision 6439)
+++ 	(revision )
@@ -1,364 +1,0 @@
-"""
-
-A fast algorithm to generate necklaces with fixed content
-Source 	Theoretical Computer Science archive
-Volume 301 ,  Issue 1-3  (May 2003) table of contents
-Pages: 477 - 489  
-Year of Publication: 2003
-ISSN:0304-3975
-Author 	
-Joe Sawada 	 Department of Computer Science, University of Toronto, 10 King's College Road, Toronto, Ont. Canada M5S 1A4
-Publisher 	
-Elsevier Science Publishers Ltd.   Essex, UK
-
-"""
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 combinat import CombinatorialClass, CombinatorialObject
-from sage.combinat.composition import Composition, Compositions
-from sage.rings.all import euler_phi,factorial, divisors, gcd, moebius, Integer
-from sage.misc.misc import prod
-from sage.combinat.misc import DoublyLinkedList
-import __builtin__
-import itertools
-import necklace
-from integer_vector import IntegerVectors
-import word
-
-def LyndonWords(e, k=None):
-    """
-    Returns the combinatorial class of Lyndon words.
-
-    EXAMPLES:
-      If e is an integer, then e specifies the length of the
-      alphabet; k must also be specified in this case.
-      
-        sage: LW = LyndonWords(3,3); LW
-        Lyndon words from an alphabet of size 3 of length 3
-        sage: LW.first()
-        [1, 1, 2]
-        sage: LW.last()
-        [2, 3, 3]
-        sage: LW.random() #
-        [1, 1, 2]
-        sage: LW.count()
-        8
-
-      If e is a (weak) composition, then it returns the class of
-      Lyndon words that have evaluation e.
-
-        sage: LyndonWords([2, 0, 1]).list()
-        [[1, 1, 3]]
-        sage: LyndonWords([2, 0, 1, 0, 1]).list()
-        [[1, 1, 3, 5], [1, 1, 5, 3], [1, 3, 1, 5]]
-        sage: LyndonWords([2, 1, 1]).list()
-        [[1, 1, 2, 3], [1, 1, 3, 2], [1, 2, 1, 3]]
-    """
-    if isinstance(e, (int, Integer)):
-        if e > 0:
-            if not isinstance(k, (int, Integer)):
-                raise TypeError, "k must be a non-negative integer"
-            if k < 0:
-                raise TypeError, "k must be a non-negative integer"
-            return LyndonWords_nk(e, k)
-    elif e in Compositions():
-        return LyndonWords_evaluation(e)
-    
-    raise TypeError, "e must be a positive integer or a composition"
-
-class LyndonWords_evaluation(CombinatorialClass):
-    def __init__(self, e):
-        """
-        TESTS:
-            sage: LW21 = LyndonWords([2,1]); LW21
-            Lyndon words with evaluation [2, 1]
-            sage: LW21 == loads(dumps(LW21))
-            True
-        """
-        self.e = Composition(e)
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(LyndonWords([2,1,1]))
-            'Lyndon words with evaluation [2, 1, 1]'
-        """
-        return "Lyndon words with evaluation %s"%self.e
-
-    def __contains__(self, x):
-        """
-        EXAMPLES:
-            sage: [1,2,1,2] in LyndonWords([2,2])
-            False
-            sage: [1,1,2,2] in LyndonWords([2,2])
-            True
-            sage: all([ lw in LyndonWords([2,1,3,1]) for lw in LyndonWords([2,1,3,1])])
-            True
-        """
-        if x not in necklace.Necklaces(self.e):
-            return False
-        
-        #Check to make sure that x is aperiodic
-        xl = list(x)
-        n = sum(self.e)
-        cyclic_shift = xl[:]
-        for i in range(n - 1):
-            cyclic_shift = cyclic_shift[1:] + cyclic_shift[:1]
-            if cyclic_shift == xl:
-                return False
-
-        return True
-
-    def count(self):
-        """
-        Returns the number of Lyndon words with the
-        evaluation e.
-
-        EXAMPLES:
-            sage: LyndonWords([]).count()
-            0
-            sage: LyndonWords([2,2]).count()
-            1
-            sage: LyndonWords([2,3,2]).count()
-            30
-
-          Check to make sure that the count matches up with the
-          number of Lyndon words generated.
-
-            sage: comps = [[],[2,2],[3,2,7],[4,2]]+Compositions(4).list()
-            sage: lws = [ LyndonWords(comp) for comp in comps]
-            sage: all( [ lw.count() == len(lw.list()) for lw in lws] )
-            True
-
-        """
-        evaluation = self.e
-        le = __builtin__.list(evaluation)
-        if len(evaluation) == 0:
-            return 0
-
-        n = sum(evaluation)
-
-        return sum([moebius(j)*factorial(n/j) / prod([factorial(ni/j) for ni in evaluation]) for j in divisors(gcd(le))])/n
-
-
-    def iterator(self):
-        """
-        An iterator for the Lyndon words with evaluation e.
-
-        EXAMPLES:
-            sage: LyndonWords([1]).list()    #indirect test
-            [[1]]
-            sage: LyndonWords([2]).list()    #indirect test
-            []
-            sage: LyndonWords([3]).list()    #indirect test
-            []
-            sage: LyndonWords([3,1]).list()  #indirect test
-            [[1, 1, 1, 2]]
-            sage: LyndonWords([2,2]).list()  #indirect test
-            [[1, 1, 2, 2]]
-            sage: LyndonWords([1,3]).list()  #indirect test
-            [[1, 2, 2, 2]]
-            sage: LyndonWords([3,3]).list()  #indirect test
-            [[1, 1, 1, 2, 2, 2], [1, 1, 2, 1, 2, 2], [1, 1, 2, 2, 1, 2]]
-            sage: LyndonWords([4,3]).list()  #indirect test
-            [[1, 1, 1, 1, 2, 2, 2],
-             [1, 1, 1, 2, 1, 2, 2],
-             [1, 1, 1, 2, 2, 1, 2],
-             [1, 1, 2, 1, 1, 2, 2],
-             [1, 1, 2, 1, 2, 1, 2]]
-             
-        """
-        if self.e == []:
-            return
-
-        for z in necklace._sfc(self.e, equality=True):
-            yield map(_add_one, z)
-
-
-def _add_one(x):
-    return x+1
-
-class LyndonWords_nk(CombinatorialClass):
-    def __init__(self, n, k):
-        """
-        TESTS:
-            sage: LW23 = LyndonWords(2,3); LW23
-            Lyndon words from an alphabet of size 2 of length 3
-            sage: LW23== loads(dumps(LW23))
-            True
-        """
-        self.n = Integer(n)
-        self.k = Integer(k)
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(LyndonWords(2, 3))
-            'Lyndon words from an alphabet of size 2 of length 3'
-        """
-        return "Lyndon words from an alphabet of size %s of length %s"%(self.n, self.k)
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: LW33 = LyndonWords(3,3)
-            sage: all([lw in LW33 for lw in LW33])
-            True
-        """
-
-        #Get the content of x and create
-        c = filter(lambda x: x!=0, word.evaluation(x))
-
-        #Change x to the "standard form"
-        d = {}
-        for i in x:
-            d[i] = 1
-        temp = [i for i in sorted(d.keys())]
-        new_x = map( lambda i: temp.index(i)+1, x )
-
-        #Check to see if it is in the Lyndon
-        return new_x in LyndonWords_evaluation(c)
-
-    def count(self):
-        """
-        TESTS:
-            sage: [ LyndonWords(3,i).count() for i in range(1, 11) ]
-            [3, 3, 8, 18, 48, 116, 312, 810, 2184, 5880]
-        """
-        if self.k == 0:
-            return 1
-        else:
-            s = 0
-            for d in divisors(self.k):
-                s += moebius(d)*(self.n**(self.k/d))
-        return s/self.k
-
-    def iterator(self):
-        """
-        TESTS:
-           sage: LyndonWords(3,3).list()
-           [[1, 1, 2],
-            [1, 1, 3],
-            [1, 2, 2],
-            [1, 2, 3],
-            [1, 3, 2],
-            [1, 3, 3],
-            [2, 2, 3],
-            [2, 3, 3]]
-        """
-        for c in IntegerVectors(self.k, self.n):
-            cf = filter(lambda x: x != 0, c)
-            nonzero_indices = []
-            for i in range(len(c)):
-                if c[i] != 0:
-                    nonzero_indices.append(i)
-            for lw in LyndonWords_evaluation(cf):
-                yield map(lambda x: nonzero_indices[x-1]+1, lw)
-
-
-def StandardBracketedLyndonWords(n, k):
-    """
-    Returns the combinatorial class of standard bracketed Lyndon
-    words from [1, ..., n] of length k.  These are in one to one
-    correspondence with the Lyndon words and form a basis for
-    the subspace of degree k of the free Lie algebra of rank n.
-
-    EXAMPLES:
-        sage: SBLW33 = StandardBracketedLyndonWords(3,3); SBLW33
-        Standard bracketed Lyndon words from an alphabet of size 3 of length 3  
-        sage: SBLW33.first()
-        [1, [1, 2]]
-        sage: SBLW33.last()
-        [[2, 3], 3]
-        sage: SBLW33.count()
-        8
-        sage: SBLW33.random() #random
-        [2, [2, 3]]
-    """
-    return StandardBracketedLyndonWords_nk(n,k)
-
-class StandardBracketedLyndonWords_nk(CombinatorialClass):
-    def __init__(self, n, k):
-        """
-        TESTS:
-            sage: SBLW = StandardBracketedLyndonWords(3, 2)
-            sage: SBLW == loads(dumps(SBLW))
-            True
-        """
-        self.n = Integer(n)
-        self.k = Integer(k)
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(StandardBracketedLyndonWords(3, 3))
-            'Standard bracketed Lyndon words from an alphabet of size 3 of length 3'
-        """
-        return "Standard bracketed Lyndon words from an alphabet of size %s of length %s"%(self.n, self.k)
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: StandardBracketedLyndonWords(3, 3).count()
-            8
-            sage: StandardBracketedLyndonWords(3, 4).count()
-            18
-        """
-        return LyndonWords_nk(self.n,self.k).count()
-
-    def iterator(self):
-        """
-        EXAMPLES:
-            sage: StandardBracketedLyndonWords(3, 3).list()
-            [[1, [1, 2]],
-             [1, [1, 3]],
-             [[1, 2], 2],
-             [1, [2, 3]],
-             [[1, 3], 2],
-             [[1, 3], 3],
-             [2, [2, 3]],
-             [[2, 3], 3]]
-        """
-        for lw in LyndonWords_nk(self.n, self.k):
-            yield standard_bracketing(lw)
-            
-
-def standard_bracketing(lw):
-    """
-    Returns the standard bracketing of a Lyndon word lw.
-
-    EXAMPLES:
-        sage: import sage.combinat.lyndon_word as lyndon_word
-        sage: map( lyndon_word.standard_bracketing, LyndonWords(3,3) )
-        [[1, [1, 2]],
-         [1, [1, 3]],
-         [[1, 2], 2],
-         [1, [2, 3]],
-         [[1, 3], 2],
-         [[1, 3], 3],
-         [2, [2, 3]],
-         [[2, 3], 3]]
-    """
-    n = max(lw)
-    k = len(lw)
-    
-    if len(lw) == 1:
-        return lw[0]
-        
-    for i in range(1,len(lw)):
-        if lw[i:] in LyndonWords(n,k):
-            return [ standard_bracketing( lw[:i] ), standard_bracketing(lw[i:]) ]
-        
Index: age/combinat/misc.py
===================================================================
--- sage/combinat/misc.py	(revision 6439)
+++ 	(revision )
@@ -1,222 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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/
-#*****************************************************************************
-
-
-class DoublyLinkedList():
-    """
-    A doubly linked list class that provides constant time hiding and unhiding
-    of entries.
-
-    Note that this list's indexing is 1-based.
-    
-    EXAMPLES:
-        sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3]); dll
-        Doubly linked list of [1, 2, 3]: [1, 2, 3]
-        sage: dll.hide(1); dll
-        Doubly linked list of [1, 2, 3]: [2, 3]
-        sage: dll.unhide(1); dll
-        Doubly linked list of [1, 2, 3]: [1, 2, 3]
-        sage: dll.hide(2); dll
-        Doubly linked list of [1, 2, 3]: [1, 3]
-        sage: dll.unhide(2); dll
-        Doubly linked list of [1, 2, 3]: [1, 2, 3]
-    """
-    def __init__(self, l):
-        """
-        TESTS:
-            sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3])
-            sage: dll == loads(dumps(dll))
-            True
-        """
-        n = len(l)
-        self.l = l
-        self.next_value = {}
-        self.next_value['begin'] = l[0]
-        self.next_value[l[n-1]] = 'end'
-        for i in xrange(n-1):
-            self.next_value[l[i]] = l[i+1]
-        
-        self.prev_value = {}
-        self.prev_value['end'] = l[-1]
-        self.prev_value[l[0]] = 'begin'
-        for i in xrange(1,n):
-            self.prev_value[l[i]] = l[i-1]        
-
-    def __cmp__(self, x):
-        """
-        TESTS:
-            sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3])
-            sage: dll2 = sage.combinat.misc.DoublyLinkedList([1,2,3])
-            sage: dll == dll2
-            True
-            sage: dll.hide(1)
-            sage: dll == dll2
-            False
-        """
-        if not isinstance(x, DoublyLinkedList):
-            return -1
-        if self.l != x.l:
-            return -1
-        if self.next_value != x.next_value:
-            return -1
-        if self.prev_value != x.prev_value:
-            return -1
-        return 0
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(sage.combinat.misc.DoublyLinkedList([1,2,3]))
-            'Doubly linked list of [1, 2, 3]: [1, 2, 3]'
-        """
-        return "Doubly linked list of %s: %s"%(self.l, list(self))
-    
-    def __iter__(self):
-        """
-        TESTS:
-            sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3])
-            sage: list(dll)
-            [1, 2, 3]
-        """
-        j = self.next_value['begin']
-        while j != 'end':
-            yield j
-            j = self.next_value[j]
-
-    def hide(self, i):
-        """
-        TESTS:
-            sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3])
-            sage: dll.hide(1)
-            sage: list(dll)
-            [2, 3]
-        """
-        self.next_value[self.prev_value[i]] = self.next_value[i]
-        self.prev_value[self.next_value[i]] = self.prev_value[i]
-
-    def unhide(self,i):
-        """
-        TESTS:
-            sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3])
-            sage: dll.hide(1); dll.unhide(1)
-            sage: list(dll)
-            [1, 2, 3]
-        """
-        self.next_value[self.prev_value[i]] = i
-        self.prev_value[self.next_value[i]] = i
-
-    def head(self):
-        """
-        TESTS:
-            sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3])
-            sage: dll.head()
-            1
-            sage: dll.hide(1)
-            sage: dll.head()
-            2
-        """
-        return self.next_value['begin']
-    
-    def next(self, j):
-        """
-        TESTS:
-            sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3])
-            sage: dll.next(1)
-            2
-            sage: dll.hide(2)
-            sage: dll.next(1)
-            3
-        """
-        return self.next_value[j]
-
-    def prev(self, j):
-        """
-        TESTS:
-            sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3])
-            sage: dll.prev(3)
-            2
-            sage: dll.hide(2)
-            sage: dll.prev(3)
-            1
-        """
-        return self.prev_value[j]
-
-    
-
-def check_integer_list_constraints(l, **kwargs):
-    if 'singleton' in kwargs and kwargs['singleton']:
-        singleton = True
-        result = [ l ]
-        n = sum(l)
-        del kwargs['singleton']
-    else:
-        singleton = False
-        if len(l) > 0:
-            n = sum(l[0])
-            result = l
-        else:
-            return []
-
-    
-    min_part = kwargs.get('min_part', None)
-    max_part = kwargs.get('max_part', None)
-
-    min_length = kwargs.get('min_length', None)
-    max_length = kwargs.get('max_length', None)
-
-    min_slope = kwargs.get('min_slope', None)
-    max_slope = kwargs.get('max_slope', None)
-
-    length = kwargs.get('length', None)
-
-    inner = kwargs.get('inner', None)
-    outer = kwargs.get('outer', None)
-    
-    #Preprocess the constraints
-    if outer != None:
-        max_length = len(outer)
-        for i in range(max_length):
-            if outer[i] == "inf":
-                outer[i] = n+1
-    if inner != None:
-        min_length = len(inner)
-   
-    if length != None:
-        max_length = length
-        min_length = length
-
-    filters = {}
-    filters['length'] = lambda x: len(x) == length
-    filters['min_part'] = lambda x: min(x) >= min_part
-    filters['max_part'] = lambda x: max(x) <= max_part
-    filters['min_length'] = lambda x: len(x) >= min_length
-    filters['max_length'] = lambda x: len(x) <= max_length
-    filters['min_slope'] = lambda x: min([x[i+1]-x[i] for i in
-                                       range(len(x)-1)]+[min_slope+1]) >= min_slope
-    filters['max_slope'] = lambda x: max([x[i+1]-x[i] for i in
-                                       range(len(x)-1)]+[max_slope-1]) <= max_slope
-    filters['outer'] = lambda x: len(outer) >= len(x) and min([outer[i]-x[i] for i in range(len(x))]) >= 0
-    filters['inner'] = lambda x: len(x) >= len(inner) and min([inner[i]-x[i] for i in range(len(inner))]) <= 0
-
-    for key in kwargs:
-        result = filter( filters[key], result )
-
-    if singleton:
-        try:
-            return result[0]
-        except IndexError:
-            return None
-    else:
-        return result
Index: age/combinat/multichoose_nk.py
===================================================================
--- sage/combinat/multichoose_nk.py	(revision 6439)
+++ 	(revision )
@@ -1,100 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.rings.arith import binomial
-import random as rnd
-
-def count(n,k):
-    """
-    Returns the number of multichoices of k things from a list
-    of n things.
-
-    EXAMPLES:
-        sage: multichoose_nk.count(3,2)
-        6
-    """
-    return binomial(n+k-1,k)
-
-def iterator(n,k):
-    """
-    An iterator for all multichoies of k thinkgs from range(n).
-
-    EXAMPLES:
-        sage: [c for c in multichoose_nk.iterator(3,2)]
-        [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]
- 
-    """
-    dif = 0
-    if k == 0:
-        yield []
-        return
-
-    if n < 1+(k-1)*dif:
-        return
-    else:
-        subword = [ i*dif for i in range(k) ]
-
-    yield subword[:]
-    finished = False
-
-    while not finished:    
-        #Find the biggest element that can be increased
-        if subword[-1] < n-1:
-            subword[-1] += 1
-            yield subword[:]
-            continue
-
-        finished = True
-        for i in reversed(range(k-1)):
-            if subword[i]+dif < subword[i+1]:
-                subword[i] += 1
-                #Reset the bigger elements
-                for j in range(1,k-i):
-                    subword[i+j] = subword[i]+j*dif
-                yield subword[:]
-                finished = False
-                break
-
-    return 
-        
-def list(n,k,repitition=False):
-    """
-    Returns a list of all the multichoices of k things from range(n).
-
-    EXAMPLES:
-        sage: multichoose_nk.list(3,2)
-        [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]
-
-    """
-
-    return [c for c in iterator(n,k)]
-
-def random(n,k):
-    """
-    Returns a random multichoice of k things from range(n).
-
-    EXAMPLES:
-        sage: multichoose_nk.random(5,2) #random
-        [0,3]
-        sage: multichoose_nk.random(5,2) #random
-        [2,2]   
-    """
-    rng = range(n)
-    r = []
-    for i in range(k):
-        r.append( rnd.choice(rng))
-        
-    r.sort()
-    return r
Index: age/combinat/necklace.py
===================================================================
--- sage/combinat/necklace.py	(revision 6439)
+++ 	(revision )
@@ -1,393 +1,0 @@
-"""
-
-A fast algorithm to generate necklaces with fixed content
-Source 	Theoretical Computer Science archive
-Volume 301 ,  Issue 1-3  (May 2003) table of contents
-Pages: 477 - 489  
-Year of Publication: 2003
-ISSN:0304-3975
-Author 	
-Joe Sawada 	 Department of Computer Science, University of Toronto, 10 King's College Road, Toronto, Ont. Canada M5S 1A4
-Publisher 	
-Elsevier Science Publishers Ltd.   Essex, UK
-
-"""
-
-
-
-    
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.combinat.composition import Composition, Composition_class
-from combinat import CombinatorialClass, CombinatorialObject
-from sage.rings.arith import euler_phi,factorial, divisors, gcd
-from sage.rings.integer import Integer
-from sage.misc.misc import prod
-from sage.combinat.misc import DoublyLinkedList
-import __builtin__
-import itertools
-
-
-
-def Necklaces(e):
-    """
-    Returns the combinatorial class of necklaces with
-    evaluation e.
-
-    EXAMPLES:
-        sage: Necklaces([2,1,1])
-        Necklaces with evaluation [2, 1, 1]
-        sage: Necklaces([2,1,1]).count()
-        3
-        sage: Necklaces([2,1,1]).first()
-        [1, 1, 2, 3]
-        sage: Necklaces([2,1,1]).last()
-        [1, 2, 1, 3]
-        sage: Necklaces([2,1,1]).list()
-        [[1, 1, 2, 3], [1, 1, 3, 2], [1, 2, 1, 3]]
-        
-    """
-    return Necklaces_evaluation(e)
-
-class Necklaces_evaluation(CombinatorialClass):
-    def __init__(self, e):
-        """
-        TESTS:
-            sage: N = Necklaces([2,2,2])
-            sage: N == loads(dumps(N))
-            True
-        """
-        if isinstance(e, Composition_class):
-            self.e = e
-        else:
-            self.e = Composition(e)
-            
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Necklaces([2,1,1]))
-            'Necklaces with evaluation [2, 1, 1]'
-        """
-        return "Necklaces with evaluation %s"%self.e
-
-    def __contains__(self, x):
-        """
-        EXAMPLES:
-            sage: [2,1,2,1] in Necklaces([2,2])
-            False
-            sage: [1,2,1,2] in Necklaces([2,2])
-            True
-            sage: [1,1,2,2] in Necklaces([2,2])
-            True
-            sage: all([ n in Necklaces([2,1,3,1]) for n in Necklaces([2,1,3,1])])
-            True
-        """
-        xl = list(x)
-        n = sum(self.e)
-        e = [0]*len(self.e)
-        if len(xl) != n:
-            return False
-
-        #Check to make sure xl is a list of integers
-        for i in xl:
-            if not isinstance(i, (int, Integer)):
-                return False
-            if i <= 0:
-                return False
-            if i > n:
-                return False
-            e[i-1] += 1
-
-        #Check to make sure the evaluation is the same
-        if e != self.e:
-            return False
-
-        #Check to make sure that x is lexicographically less
-        #than all of its cyclic shifts
-        cyclic_shift = xl[:]
-        for i in range(n - 1):
-            cyclic_shift = cyclic_shift[1:] + cyclic_shift[:1]
-            if cyclic_shift < xl:
-                return False
-
-        return True
-    
-    def count(self):
-        """
-        Returns the number of integer necklaces with the
-        evaluation e.
-
-        EXAMPLES:
-            sage: Necklaces([]).count()
-            0
-            sage: Necklaces([2,2]).count()
-            2
-            sage: Necklaces([2,3,2]).count()
-            30
-
-          Check to make sure that the count matches up with the
-          number of Lyndon words generated.
-
-            sage: comps = [[],[2,2],[3,2,7],[4,2]]+Compositions(4).list()
-            sage: ns = [ Necklaces(comp) for comp in comps]
-            sage: all( [ n.count() == len(n.list()) for n in ns] )
-            True       
-        """
-        evaluation = self.e
-        le = __builtin__.list(evaluation)
-        if len(evaluation) == 0:
-            return 0
-
-        n = sum(evaluation)
-
-        return sum([euler_phi(j)*factorial(n/j) / prod([factorial(ni/j) for ni in evaluation]) for j in divisors(gcd(le))])/n
-
-
-    def iterator(self):
-        """
-        An iterator for the integer necklaces iwth evaluation e.
-
-        EXAMPLES:
-            sage: Necklaces([]).list()    #indirect test
-            []
-            sage: Necklaces([1]).list()   #indirect test
-            [[1]]
-            sage: Necklaces([2]).list()   #indirect test
-            [[1, 1]]
-            sage: Necklaces([3]).list()   #indirect test
-            [[1, 1, 1]]
-            sage: Necklaces([3,3]).list() #indirect test
-            [[1, 1, 1, 2, 2, 2],
-             [1, 1, 2, 1, 2, 2],
-             [1, 1, 2, 2, 1, 2],
-             [1, 2, 1, 2, 1, 2]]
-            sage: Necklaces([2,1,3]).list() #indirect test
-            [[1, 1, 2, 3, 3, 3],
-             [1, 1, 3, 2, 3, 3],
-             [1, 1, 3, 3, 2, 3],
-             [1, 1, 3, 3, 3, 2],
-             [1, 2, 1, 3, 3, 3],
-             [1, 2, 3, 1, 3, 3],
-             [1, 2, 3, 3, 1, 3],
-             [1, 3, 1, 3, 2, 3],
-             [1, 3, 1, 3, 3, 2],
-             [1, 3, 2, 1, 3, 3]]
-        """
-        if self.e == []:
-            return 
-        for z in _sfc(self.e):
-            yield map(lambda x: x+1, z)
-
-            
-
-##############################
-#Fast Fixed Content Algorithm#
-##############################
-def _ffc(content, equality=False):
-    e = list(content)
-    a = [len(e)-1]*sum(e)
-    r = [0] * sum(e)
-    a[0] = 0
-    e[0] -= 1
-    k = len(e)
-    l = range(k)
-    
-    rng_k = range(k)
-    rng_k.reverse()
-    dll = DoublyLinkedList(rng_k)
-    if e[0] == 0:
-        dll.hide(0)
-        
-    j = dll.head()
-    for x in _fast_fixed_content(a, e, 2, 1, k, r, 2, dll, equality=equality):
-        yield x
-    
-def _fast_fixed_content(a, content, t, p, k, r, s, dll, equality=False):
-    n = len(a)
-    if content[k-1] == n - t + 1:
-        if content[k-1] == r[t-p-1]:
-            if equality:
-                if n == p:
-                    yield a
-            else:
-                if n % p == 0:
-                    yield a
-        elif content[k-1] > r[t-p-1]:
-            yield a
-    elif content[0] != n-t+1:
-        j = dll.head()
-        sp = s
-        while j != 'end' and j >= a[t-p-1]:
-            #print s, j
-            r[s-1] = t-s
-            a[t-1] = j
-            content[j] -= 1
-
-            if content[j] == 0:
-                dll.hide(j)
-
-            if j != k-1:
-                sp = t+1
-                
-            if j == a[t-p-1]:
-                for x in _fast_fixed_content(a[:], content, t+1, p+0, k, r, sp, dll, equality=equality):
-                    yield x
-            else:
-                for x in _fast_fixed_content(a[:], content, t+1, t+0, k, r, sp, dll, equality=equality):
-                    yield x
-
-            if content[j] == 0:
-                dll.unhide(j)
-                
-            content[j] += 1
-            j = dll.next(j)
-        a[t-1] = k-1
-    return
-
-
-################################
-# List Fixed Content Algorithm #
-################################
-def _lfc(content, equality=False):
-    content = list(content)
-    a = [0]*sum(content)
-    content[0] -= 1
-    k = len(content)
-    l = range(k)
-
-    rng_k = range(k)
-    rng_k.reverse()
-    dll = DoublyLinkedList(rng_k)
-
-    if content[0] == 0:
-        dll.hide(0)
-
-    j = dll.head()
-    for z in _list_fixed_content(a, content, 2, 1, k, dll, equality=equality):
-        yield z
-
-def _list_fixed_content(a, content, t, p, k, dll, equality=False):
-    n = len(a)
-    if t > n:
-        if equality:
-            if n == p:
-                yield a
-        else:
-            if n % p == 0:
-                yield a
-    else:
-        j = dll.head()
-        while j != 'end' and j >= a[t-p-1]:
-            a[t-1] = j
-            content[j] -= 1
-
-            if content[j] == 0:
-                dll.hide(j)
-                
-            if j == a[t-p-1]:
-                for z in _list_fixed_content(a[:], content[:], t+1, p+0, k, dll, equality=equality):
-                    yield z
-            else:
-                for z in _list_fixed_content(a[:], content[:], t+1, t+0, k, dll, equality=equality):
-                    yield z
-
-            if content[j] == 0:
-                dll.unhide(j)
-                
-            content[j] += 1
-            j = dll.next(j)
-                
-
-
-################################
-#Simple Fixed Content Algorithm#
-################################
-def _sfc(content, equality=False):
-    """
-    TESTS:
-        sage: import sage.combinat.necklace as necklace
-        sage: list(necklace._sfc([3,3]))
-        [[0, 0, 0, 1, 1, 1],
-         [0, 0, 1, 0, 1, 1],
-         [0, 0, 1, 1, 0, 1],
-         [0, 1, 0, 1, 0, 1]]
-    """
-    content = list(content)
-    a = [0]*sum(content)
-    content[0] -= 1
-    k = len(content)
-    return _simple_fixed_content(a, content, 2, 1, k, equality=equality)
-
-def _simple_fixed_content(a, content, t, p, k, equality=False):
-    n = len(a)
-    if t > n:
-        if equality:
-            if n == p:
-                yield a
-        else:
-            if n % p == 0:
-                yield a
-    else:
-        r = range(a[t-p-1],k)
-        for j in r:
-            if content[j] > 0:
-                a[t-1] = j
-                content[j] -= 1
-                if j == a[t-p-1]:
-                    for z in _simple_fixed_content(a[:], content, t+1, p+0, k, equality=equality):
-                        yield z
-                else:
-                    for z in _simple_fixed_content(a[:], content, t+1, t+0, k, equality=equality):
-                        yield z
-                content[j] += 1
-            
-
-def _lyn(w):
-    """
-    Returns the length of the longest prefix of w that
-    is a Lyndon word.
-
-    From Theorem 1.
-
-    EXAMPLES:
-        sage: import sage.combinat.necklace as necklace
-        sage: necklace._lyn([0,1,1,0,0,1,2])
-        3
-        sage: necklace._lyn([0,0,0,1])
-        4
-        sage: necklace._lyn([2,1,0,0,2,2,1])
-        1
-    """
-
-    p = 1
-    k = max(w)+1
-    for i in range(1, len(w)):
-        b = w[i]
-        a = w[:i]
-        #print "a, b, a[i-p]:", a, b, a[i-p]
-        if b < a[i-p] or b > k-1:
-            return p
-        elif b == a[i-p]:
-            pass
-        else:
-            p = i+1
-    return p
-        
-
-
-
Index: age/combinat/partition.py
===================================================================
--- sage/combinat/partition.py	(revision 6457)
+++ 	(revision )
@@ -1,1774 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.interfaces.all import gap, maxima
-from sage.rings.all import QQ, RR, ZZ
-from sage.misc.all import prod, sage_eval
-from sage.rings.arith import factorial, gcd
-from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
-from sage.calculus.calculus import Function_ceil, log, SymbolicVariable, Function_sinh
-from sage.calculus.functional import diff
-import sage.combinat.generator as generator
-import sage.combinat.misc as misc
-import sage.combinat.skew_partition
-from sage.rings.integer import Integer
-from UserList import UserList
-import __builtin__
-from sage.functions.constants import pi
-ceil = Function_ceil()
-sinh = Function_sinh()
-from combinat import CombinatorialClass, CombinatorialObject
-import partitions as partitions_ext
-from sage.libs.all import pari
-
-def Partition(l=None, exp=None, core_and_quotient=None):
-    """
-    Returns a partition object.
-
-    EXAMPLES:
-        sage: Partition(exp=[2,1,1])
-        [3, 2, 1, 1]
-        sage: Partition(core_and_quotient=([2,1], [[2,1],[3],[1,1,1]]))
-        [11, 5, 5, 3, 2, 2, 2]
-        sage: Partition([3,2,1])
-        [3, 2, 1]
-    """
-    number_of_arguments = 0
-    for arg in ['l', 'exp', 'core_and_quotient']:
-        if eval(arg) != None:
-            number_of_arguments += 1
-
-    if number_of_arguments != 1:
-        raise ValueError, "you must specify exactly one argument"
-
-    if l != None:
-        if sum(l) == 0:
-            l = []
-        return Partition_class(l)
-    elif exp != None:
-        return from_exp(exp)
-    else:
-        return from_core_and_quotient(*core_and_quotient)
-    
-
-def from_exp(a):
-    """
-    Returns a partition from its list of multiplicities.
-
-    EXAMPLES:
-        sage: partition.from_exp([1,2,1])
-        [3, 2, 2, 1]
-    """
-
-    p = []
-    for i in reversed(range(len(a))):
-        p += [i+1]*a[i]
-
-    return Partition(p)
-
-
-    
-def from_core_and_quotient(core, quotient):
-    """
-    Returns a partition from its r-core and r-quotient.
-
-    Algorithm from mupad-combinat.
-
-    EXAMPLES:
-        sage: partition.from_core_and_quotient([2,1], [[2,1],[3],[1,1,1]])
-        [11, 5, 5, 3, 2, 2, 2]
-    """
-    length = len(quotient)
-    k = length*max( [ceil(len(core)/length),len(core)] + [len(q) for q in quotient] ) + length
-    v = [ core[i]-(i+1)+1 for i in range(len(core))] + [ -i + 1 for i in range(len(core)+1,k+1) ]
-    w = [ filter(lambda x: (x-i) % length == 0, v) for i in range(1, length+1) ]
-    new_w = []
-    for i in range(length):
-        new_w += [ w[i][j] + length*quotient[i][j] for j in range(len(quotient[i]))]
-        new_w += [ w[i][j] for j in range(len(quotient[i]), len(w[i])) ]
-    new_w.sort()
-    new_w.reverse()
-    return filter(lambda x: x != 0, [new_w[i-1]+i-1 for i in range(1, len(new_w)+1)])
-
-    
-class Partition_class(CombinatorialObject):
-    def ferrers_diagram(self):
-        """
-        Return the Ferrers diagram of pi.
-
-        INPUT:
-            pi -- a partition, given as a list of integers. 
-
-        EXAMPLES:
-            sage: print Partition([5,5,2,1]).ferrers_diagram()
-            *****
-            *****
-            **
-            *        
-            sage: pi = Partitions(10).list()[11] ## [6,1,1,1,1]
-            sage: print pi.ferrers_diagram()
-            ******
-            *
-            *
-            *
-            *
-            sage: pi = Partitions(10).list()[8] ## [6, 3, 1]
-            sage: print pi.ferrers_diagram()
-            ******
-            ***
-            *
-        """
-        return '\n'.join(['*'*p for p in self])
-
-
-    def __div__(self, p):
-        """
-        Returns the skew partition self/p.
-
-        EXAMPLES:
-            sage: p = Partition([3,2,1])
-            sage: p/[1,1]
-            [[3, 2, 1], [1, 1]]
-            sage: p/[3,2,1]
-            [[3, 2, 1], [3, 2, 1]]
-            
-        """
-        if not self.dominates(Partition_class(p)):
-            raise ValueError, "the partition must dominate p"
-
-        return sage.combinat.skew_partition.SkewPartition([self[:], p])
-        
-    def power(self,k):
-        """
-        partition_power( pi, k ) returns the partition corresponding to the 
-        $k$-th power of a permutation with cycle structure pi 
-        (thus describes the powermap of symmetric groups).
-
-        Wraps GAP's PowerPartition.
-
-        EXAMPLES:
-            sage: p = Partition([5,3])
-            sage: p.power(1)
-            [5, 3]
-            sage: p.power(2)
-            [5, 3]
-            sage: p.power(3)
-            [5, 1, 1, 1]
-            sage: p.power(4)
-            [5, 3]
-
-         Now let us compare this to the power map on $S_8$:
-
-            sage: G = SymmetricGroup(8)
-            sage: g = G([(1,2,3,4,5),(6,7,8)])
-            sage: g
-            (1,2,3,4,5)(6,7,8)
-            sage: g^2
-            (1,3,5,2,4)(6,8,7)
-            sage: g^3
-            (1,4,2,5,3)
-            sage: g^4
-            (1,5,4,3,2)(6,7,8)
-
-        """
-        ans=gap.eval("PowerPartition(%s,%s)"%(self,ZZ(k)))
-        return Partition_class(eval(ans))
-
-    def next(self):
-        """
-        Returns the partition that lexicographically follows
-        the partition p.  If p is the last partition, then
-        it returns False.
-
-        EXAMPLES:
-            sage: Partition([4]).next()
-            [3, 1]
-            sage: Partition([1,1,1,1]).next()
-            False
-        """
-        p = self
-        n = 0
-        m = 0
-        for i in p:
-            n += i
-            m += 1
-        
-        next_p = p[:] + [1]*(n - len(p))
-
-        #Check to see if we are at the last (all ones) partition
-        if p == [1]*n:
-            return False
-
-        #
-        #If we are not, then run the ZS1 algorithm.
-        #
-
-        #Let h be the number of non-one  entries in the
-        #partition
-        h = 0 
-        for i in next_p:
-            if i != 1:
-                h += 1
-
-        if next_p[h-1] == 2:
-            m += 1
-            next_p[h-1] = 1
-            h -= 1
-        else:
-            r = next_p[h-1] - 1
-            t = m - h + 1
-            next_p[h-1] = r
-
-            while t >= r :
-                h += 1
-                next_p[h-1] = r
-                t -= r
-
-            if t == 0:
-                m = h
-            else:
-                m = h + 1
-                if t > 1:
-                    h += 1
-                    next_p[h-1] = t
-
-        return Partition_class(next_p[:m])
-
-    def size(self):
-        """
-        Returns the size of partition p.
-
-        EXAMPLES:
-            sage: Partition([2,2]).size()
-            4
-            sage: Partition([3,2,1]).size()
-            6
-        """
-        return sum(self)
-
-    def sign(self):
-        r"""
-        partition_sign( pi ) returns the sign of a permutation with cycle structure 
-        given by the partition pi.
-
-        This function corresponds to a homomorphism from the symmetric group 
-        $S_n$ into the cyclic group of order 2, whose kernel is exactly the 
-        alternating group $A_n$. Partitions of sign $1$ are called {\it even partitions} 
-        while partitions of sign $-1$ are called {\it odd}.
-
-        Wraps GAP's SignPartition.
-
-        EXAMPLES:
-            sage: Partition([5,3]).sign()
-            1
-            sage: Partition([5,2]).sign()
-            -1
-
-        {\it Zolotarev's lemma} states that the Legendre symbol
-        $ \left(\frac{a}{p}\right)$ for an integer $a \pmod p$ ($p$ a prime number), 
-        can be computed as sign(p_a), where sign denotes the sign of a permutation
-        and p_a the permutation of the residue classes $\pmod p$ induced by 
-        modular multiplication by $a$, provided $p$ does not divide $a$.
-
-        We verify this in some examples.
-
-            sage: F = GF(11)
-            sage: a = F.multiplicative_generator();a
-            2
-            sage: plist = [int(a*F(x)) for x in range(1,11)]; plist
-            [2, 4, 6, 8, 10, 1, 3, 5, 7, 9]
-
-        This corresponds ot the permutation (1, 2, 4, 8, 5, 10, 9, 7, 3, 6)
-        (acting the set $\{1,2,...,10\}$) and to the partition [10].
-
-            sage: p = PermutationGroupElement('(1, 2, 4, 8, 5, 10, 9, 7, 3, 6)')
-            sage: p.sign()
-            -1
-            sage: Partition([10]).sign()
-            -1
-            sage: kronecker_symbol(11,2)
-            -1
-
-        Now replace $2$ by $3$:
-
-            sage: plist = [int(F(3*x)) for x in range(1,11)]; plist
-            [3, 6, 9, 1, 4, 7, 10, 2, 5, 8]
-            sage: range(1,11)
-            [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-            sage: p = PermutationGroupElement('(3,4,8,7,9)')
-            sage: p.sign()
-            1
-            sage: kronecker_symbol(3,11)
-            1
-            sage: Partition([5,1,1,1,1,1]).sign()
-            1
-
-        In both cases, Zolotarev holds.
-
-        REFERENCES:
-            http://en.wikipedia.org/wiki/Zolotarev's_lemma
-        """
-        ans=gap.eval("SignPartition(%s)"%(self))
-        return sage_eval(ans)
-
-
-    def up(self):
-        r"""
-        Returns a generator for partitions that can be obtained from pi
-        by adding a box.
-
-        EXAMPLES:
-            sage: [p for p in Partition([2,1,1]).up()]
-            [[3, 1, 1], [2, 2, 1], [2, 1, 1, 1]]
-            sage: [p for p in Partition([3,2]).up()]
-            [[4, 2], [3, 3], [3, 2, 1]]
-        """
-        p = self
-        previous = p[0] + 1
-        for i, current in enumerate(p):
-            if current < previous:
-                yield Partition(p[:i] + [ p[i] + 1 ] + p[i+1:])
-            previous = current
-        else:
-            yield Partition(p + [1])
-
-    def up_list(self):
-        """
-        Returns a list of the partitions that can be formed from the partition
-        p by adding a box.
-
-        EXAMPLES:
-            sage: Partition([2,1,1]).up_list()
-            [[3, 1, 1], [2, 2, 1], [2, 1, 1, 1]]
-            sage: Partition([3,2]).up_list()
-            [[4, 2], [3, 3], [3, 2, 1]]
-        """
-        return [p for p in self.up()]
-
-    def down(self):
-        r"""
-        Returns a generator for partitions that can be obtained from
-        p by removing a box.
-
-        EXAMPLES:
-            sage: [p for p in Partition([2,1,1]).down()]
-            [[1, 1, 1], [2, 1]]
-            sage: [p for p in Partition([3,2]).down()]
-            [[2, 2], [3, 1]]
-            sage: [p for p in Partition([3,2,1]).down()]
-            [[2, 2, 1], [3, 1, 1], [3, 2]]
-        """
-        p = self
-        for i in range(len(p)-1):
-            if p[i] > p[i+1]:
-                yield Partition(p[:i] + [ p[i]-1 ] + p[i+1:])
-
-        last = p[-1]
-        if last == 1:
-            yield Partition(p[:-1])
-        else:
-            yield Partition(p[:-1] + [ p[-1] - 1 ])
-
-
-    def down_list(self):
-        """
-        Returns a list of the partitions that can be obtained from
-        the partition p by removing a box.
-
-        EXAMPLES:
-            sage: Partition([2,1,1]).down_list()
-            [[1, 1, 1], [2, 1]]
-            sage: Partition([3,2]).down_list()
-            [[2, 2], [3, 1]]
-            sage: Partition([3,2,1]).down_list()
-            [[2, 2, 1], [3, 1, 1], [3, 2]]
-        """
-        return [p for p in self.down()]
-
-    def dominates(self, p2):
-        r"""
-        Returns True if partition p1 dominates partitions p2. Otherwise,
-        it returns False.
-
-        EXAMPLES:
-            sage: p = Partition([3,2])
-            sage: p.dominates([3,1])
-            True
-            sage: p.dominates([2,2])
-            True
-            sage: p.dominates([2,1,1])
-            False
-            sage: p.dominates([3,3])
-            False
-        """
-        p1 = self
-        sum1 = 0
-        sum2 = 0
-        if len(p2) > len(p1):
-            return False
-        for i in range(max(len(p1), len(p2))):
-            if i < len(p1):
-                sum1 += p1[i]
-            if i < len(p2):
-                sum2 += p2[i]
-            if sum2 > sum1:
-                return False
-            sum1 = 0
-            sum2 = 0
-        return True
-
-    def conjugate(self):
-        """
-        conjugate() returns the ``conjugate'' (also called 
-        ``associated'' in the literature) partition of the partition pi which is 
-        obtained by transposing the corresponding Ferrers diagram.
-
-        EXAMPLES:
-            sage: Partition([2,2]).conjugate()
-            [2, 2]
-            sage: Partition([6,3,1]).conjugate()
-            [3, 2, 2, 1, 1, 1]
-            sage: print Partition([6,3,1]).ferrers_diagram()
-            ******
-            ***
-            *
-            sage: print Partition([6,3,1]).conjugate().ferrers_diagram()
-            ***
-            **
-            **
-            *
-            *
-            *
-
-        """
-        p = self
-        if p == []:
-            return Partition([])
-        else:
-            l = len(p)
-            conj =  [l]*p[l-1]
-            for i in range(2,l+1):
-                conj += [l-i+1]*(p[l-i] - p[l-i+1])
-
-            return Partition(conj)
-
-
-    def associated(self):
-        """
-        An alias for partition.conjugate(pi).
-
-        EXAMPLES:
-            sage: Partition([4,1,1]).associated()
-            [3, 1, 1, 1]
-            sage: Partition([4,1,1]).conjugate()
-            [3, 1, 1, 1]
-            sage: Partition([5,4,2,1,1,1]).associated().associated()
-            [5, 4, 2, 1, 1, 1]
-        """
-
-        return self.conjugate()
-
-    def arm(self, i, j):
-        """
-        Returns the arm of cell (i,j) in partition p.  The arm of cell (i,j)
-        is the number of boxes that appear to the right of cell (i,j).
-        Note that i and j are 0-based indices.
-
-        EXAMPLES:
-            sage: p = Partition([2,2,1])
-            sage: p.arm(0, 0)
-            1
-            sage: p.arm(0, 1)
-            0
-            sage: p.arm(2, 0)
-            0        
-            sage: Partition([3,3]).arm(0, 0)
-            2
-        """
-        p = self
-        if i < len(p) and j < p[i]:
-            return p[i]-(j+1)
-        else:
-            #Error: invalid coordinates
-            pass
-
-    def arm_lengths(self):
-        """
-        Returns a tableau of shape p where each box is filled its arm.
-
-        EXAMPLES: 
-            sage: Partition([2,2,1]).arm_lengths()
-            [[1, 0], [1, 0], [0]]
-            sage: Partition([3,3]).arm_lengths()
-            [[2, 1, 0], [2, 1, 0]]
-        """
-        p = self
-        return [[p[i]-(j+1) for j in range(p[i])] for i in range(len(p))]
-
-
-    def leg(self, i, j):
-        """
-        Returns the leg of box (i,j) in partition p. The leg of box (i,j)
-        is defined to be the number of boxes below it in partition p.
-
-
-        EXAMPLES:
-            sage: p = Partition([2,2,1])
-            sage: p.leg(0, 0)
-            2
-            sage: p.leg(0,1)
-            1
-            sage: p.leg(2,0)
-            0        
-            sage: Partition([3,3]).leg(0, 0)
-            1        
-        """
-       
-        conj = self.conjugate()
-        if j < len(conj) and i < conj[j]:
-            return conj[j]-(i+1)
-        else:
-            #Error: invalid coordinates
-            pass
-
-    def leg_lengths(self):
-        """
-        Returns a tableau of shape p with each box filled in with
-        its leg.
-
-        EXAMPLES:
-            sage: Partition([2,2,1]).leg_lengths()
-            [[2, 1], [1, 0], [0]]
-            sage: Partition([3,3]).leg_lengths()
-            [[1, 1, 1], [0, 0, 0]]
-        """
-        p = self
-        conj = p.conjugate()
-        return [[conj[j]-(i+1) for j in range(p[i])] for i in range(len(p))]
-
-    def hook(self, i, j):
-        """
-        Returns the hook of box (i,j) in the partition p.  The hook of box
-        (i,j) is defined to be one more than the sum of number of boxes
-        to the right and the number of boxes below.
-
-        EXAMPLES:
-            sage: p = Partition([2,2,1])
-            sage: p.hook(0, 0)
-            4
-            sage: p.hook(0, 1)
-            2
-            sage: p.hook(2, 0)
-            1        
-            sage: Partition([3,3]).hook(0, 0)
-            4        
-        """
-        return self.leg(i,j)+self.arm(i,j)+1
-
-
-    def hook_lengths(self):
-        r"""
-        Returns a tableau of shape pi with the boxes filled in with the
-        hook lengths
-
-        In each box, put the sum of one plus the number of boxes horizontally to the right
-        and vertically below the box (the hook length).
-
-
-        For example, consider the partition [3,2,1] of 6 with Ferrers Diagram
-        * * *
-        * *
-        *
-        When we fill in the boxes with the hook lengths, we obtain
-        5 3 1
-        3 1
-        1
-
-        EXAMPLES:
-            sage: Partition([2,2,1]).hook_lengths()
-            [[4, 2], [3, 1], [1]]
-            sage: Partition([3,3]).hook_lengths()
-            [[4, 3, 2], [3, 2, 1]]
-            sage: Partition([3,2,1]).hook_lengths()
-            [[5, 3, 1], [3, 1], [1]]
-            sage: Partition([2,2]).hook_lengths()
-            [[3, 2], [2, 1]]
-            sage: Partition([5]).hook_lengths()
-            [[5, 4, 3, 2, 1]]
-
-
-        REFERENCES:
-            http://mathworld.wolfram.com/HookLengthFormula.html
-        """
-        p = self
-        conj = p.conjugate()
-        return [[p[i]-(i+1)+conj[j]-(j+1)+1 for j in range(p[i])] for i in range(len(p))]
-
-
-    def weighted_size(self):
-        """
-        Returns sum([i*p[i] for i in range(len(p))]).
-
-        EXAMPLES:
-            sage: Partition([2,2,1]).weighted_size()
-            9
-            sage: Partition([3,3]).weighted_size()
-            9
-        """
-        p = self
-        return sum([(i+1)*p[i] for i in range(len(p))])
-
-
-    def to_exp(self, k=0):
-        """
-        Return a list of the multiplicities of the parts of a partition.
-
-        EXAMPLES:
-            sage: Partition([3,2,2,1]).to_exp()
-            [0, 1, 2, 1]
-        """
-        p = self
-        if len(p) > 0:
-            k = max(k, p[0])
-        a = [ 0 ] * (k+1)
-        for i in p:
-            a[i] += 1
-        return a
-
-    def evaluation(self):
-        """
-        Returns the evaluation of the partition.
-
-        EXAMPLES:
-            sage: Partition([4,3,1,1]).evaluation()
-            [0, 2, 0, 1, 1]
-        """
-        return self.to_exp()
-
-    def centralizer_size(self, t=0, q=0):
-        """
-        Returns the size of the centralizer of any permuation of cycle type p.
-
-        EXAMPLES:
-            sage: Partition([2,2,1]).centralizer_size()
-            8
-            sage: Partition([2,2,2]).centralizer_size()
-            48 
-
-        REFERENCES:
-            Kerber, A. 'Algebraic Combintorics via Finite Group Action', 1.3 p24
-        """
-        p = self
-        a = p.to_exp()
-        size = prod([i**a[i]*factorial(a[i]) for i in range(1, len(a))])
-        size *= prod( [ (1-q**p[i])/(1-t**p[i]) for i in range(len(p)) ] )
-
-        return size
-
-
-    def conjugacy_class_size(self):
-        """
-        Returns the size of the conjugacy class of the symmetric group
-        indexed by the partition p.
-
-        EXAMPLES:
-            sage: Partition([2,2,2]).conjugacy_class_size()
-            15
-            sage: Partition([2,2,1]).conjugacy_class_size()
-            15
-            sage: Partition([2,1,1]).conjugacy_class_size() 
-            6
-
-
-        REFERENCES:
-            Kerber, A. 'Algebraic Combinatorics via Finite Group Action' 1.3 p24
-        """
-        
-        return factorial(sum(self))/self.centralizer_size()
-
-
-    def corners(self):
-        """
-        Returns a list of the corners of the partitions.  These are the
-        positions where we can remove a box.
-
-        EXAMPLES:
-            sage: Partition([3,2,1]).corners()
-            [[0, 2], [1, 1], [2, 0]]
-            sage: Partition([3,3,1]).corners()
-            [[1, 2], [2, 0]]
-
-        """
-        p = self
-        if p == []:
-            return []
-
-        lcors = [[0,p[0]-1]]
-        nn = len(p)
-        if nn == 1:
-            return lcors
-
-        lcors_index = 0
-        for i in range(1, nn):
-            if p[i] == p[i-1]:
-                lcors[lcors_index][0] += 1
-            else:
-                lcors.append([i,p[i]-1])
-                lcors_index += 1
-
-        return lcors
-
-
-    def outside_corners(self):
-        """
-        Returns a list of the positions where we can add a box so
-        that the shape is still a partition.
-
-        EXAMPLES:
-            sage: Partition([2,2,1]).outside_corners()
-            [[0, 2], [2, 1], [3, 0]]
-            sage: Partition([2,2]).outside_corners()
-            [[0, 2], [2, 0]]
-            sage: Partition([6,3,3,1,1,1]).outside_corners() 
-            [[0, 6], [1, 3], [3, 1], [6, 0]]
-
-        """
-        p = self
-        res = [ [0, p[0]] ]        
-        for i in range(1, len(p)):
-            if p[i-1] != p[i]:
-                res.append([i,p[i]])
-        res.append([len(p), 0])
-                
-        return res
-
-    def r_core(self, length):
-        """
-        Returns the r-core of the partition p.
-
-        EXAMPLES:
-            sage: Partition([6,3,2,2]).r_core(3)
-            [2, 1, 1]
-        """
-        p = self
-        #Normalize the length
-        remainder = len(p) % length
-        part = p[:] + [0]*remainder
-
-        #Add the canonical vector to the partition
-        part = [part[i-1] + len(part)-i for i in range(1, len(part)+1)]
-
-        for e in range(length):
-            k = e
-            for i in reversed(range(1,len(part)+1)):
-                if part[i-1] % length == e:
-                    part[i-1] = k
-                    k += length
-        part.sort()
-        part.reverse()
-
-        #Remove the canonical vector
-        part = [part[i-1]-len(part)+i for i in range(1, len(part)+1)]
-        #Select the r-core
-        return filter(lambda x: x != 0, part)
-
-    def r_quotient(self, length):
-        """
-        Returns the r-quotient of the partition p.
-
-        EXAMPLES:
-            sage: Partition([7,7,5,3,3,3,1]).r_quotient(3) #[[2], [1], [2, 2, 2]]?
-            [[1], [2, 2, 2], [2]]
-        """
-        p = self
-        #Normalize the length
-        remainder = len(p) % length
-        part = p[:] + [0]*remainder
-
-
-        #Add the canonical vector to the partition
-        part = [part[i-1] + len(part)-i for i in range(1, len(part)+1)]
-
-        result = [None]*length
-
-        for e in range(length):
-            k = e
-            tmp = []
-            for i in reversed(range(len(part))):
-                if part[i] % length == e:
-                    tmp.append((part[i]-k)/length)
-                    k += length
-
-            a = filter(lambda x: x != 0, tmp)
-            a.reverse()
-            result[e] = a
-
-        return result
-
-
-    def remove_box(self, i, j = None):
-        """
-        Returns the partiton obtained by removing a box at the end of row i.
-
-        EXAMPLES:
-            sage: Partition([2,2]).remove_box(1)
-            [2, 1]
-            sage: Partition([2,2,1]).remove_box(2)
-            [2, 2]
-            sage: #Partition([2,2]).remove_box(0)
-            
-            sage: Partition([2,2]).remove_box(1,1)
-            [2, 1]
-            sage: #Partition([2,2]).remove_box(1,0)
-        """
-
-        if i >= len(self):
-            raise ValueError, "i must be less than the length of the partition"
-
-        if j == None:
-            j = self[i] - 1
-            
-        if [i,j] not in self.corners():
-            raise ValueError, "[%d,%d] is not a corner of the partition" % (i,j)
-
-        if self[i] == 1:
-            return Partition(self[:-1])
-        else:
-            return Partition(self[:i] + [ self[i:i+1][0] - 1 ] + self[i+1:])
-
-
-
-    def k_skew(self, k):
-        r"""
-        Returns the k-skew partition.
-
-        The k-skew diagram of a k-bounded partition is the skew diagram denoted
-        $\lambda/^k$ satisfying the conditions:
-        (i) row i of $\lambda/^k$ has length $\lambda_i$
-        (ii) no cell in $\lambda/^k$ has hook-length exceeding k
-        (iii) every square above the diagram of $\lambda/^k$ has hook
-        length exceeding k.
-
-        REFERENCES:
-            Lapointe, L. and Morse, J. 'Order Ideals in Weak Subposets of Young's Lattice
-                and Associated Unimodality Conjectures'
-        
-        EXAMPLES:
-            sage: p = Partition([4,3,2,2,1,1])
-            sage: p.k_skew(4)
-            [[9, 5, 3, 2, 1, 1], [5, 2, 1]]
-        """
-
-        if len(self) == 0:
-            return sage.combinat.skew_partition.SkewPartition([[],[]])
-
-        if self[0] > k:
-            raise ValueError, "the partition must be %d-bounded" % k
-
-        #Find the k-skew diagram of the partition formed
-        #by removing the first row
-        s = Partition(self[1:]).k_skew(k)
-        
-        s_inner = s.inner()
-        s_outer = s.outer()
-        s_conj_rl = s.conjugate().row_lengths()
-        
-        #Find the leftmost column with less than
-        # or equal to kdiff boxes
-        kdiff = k - self[0]
-        
-        if s_outer == []:
-            spot = 0
-        else:
-            spot = s_outer[0]
-
-        for i in range(len(s_conj_rl)):
-            if s_conj_rl[i] <= kdiff:
-                spot = i
-                break
-
-        outer = [ self[0] + spot ] + s_outer[:]
-        if spot > 0:
-            inner = [ spot ] + s_inner[:]
-        else:
-            inner = s_inner[:]
-
-        return sage.combinat.skew_partition.SkewPartition([outer, inner])
-
-        
-    def k_conjugate(self, k):
-        """
-        Returns the k-conjugate of the partition.
-
-        The k-conjugate is the partition that is given by the columns
-        of the k-skew diagram of the partition.
-
-        EXAMPLES:
-            sage: p = Partition([4,3,2,2,1,1])
-            sage: p.k_conjugate(4)
-            [3, 2, 2, 1, 1, 1, 1, 1, 1]
-        """
-        return Partition(self.k_skew(k).conjugate().row_lengths())
-        
-    def parent(self):
-        """
-        Returns the combinatorial class of partitions of
-        sum(self).
-
-        EXAMPLES:
-            sage: Partition([3,2,1]).parent()
-            Partitions of the integer 6
-        """
-        return Partitions(sum(self[:]))
-
-    def arms_legs_coeff(self, i , j):
-        """
-        EXAMPLES:
-            sage: Partition([3,2,1]).arms_legs_coeff(1,1)
-            (-t + 1)/(-q + 1)
-            sage: Partition([3,2,1]).arms_legs_coeff(0,0)
-            (-q^2*t^3 + 1)/(-q^3*t^2 + 1)
-        """
-        QQqt = PolynomialRing(QQ, ['q', 't'])
-        (q,t) = QQqt.gens()
-        if i < len(self) and j < self[i]:
-            res =  (1-q**self.arm(i,j) * t**(self.leg(i,j)+1))
-            res /= (1-q**(self.arm(i,j)+1) * t**self.leg(i,j))
-            return res
-        else:
-            return ZZ(1)
-
-    def macdonald_coeff(self):
-        res = 1
-        for i in range(len(self)):
-            for j in range(self[i]):
-                res *= self.arms_legs_coeff(i,j)
-        return res
-
-    def jacobi_trudy(self):
-        """
-
-        EXAMPLES:
-            sage: part = Partition([3,2,1])
-            sage: jt = part.jacobi_trudy(); jt
-            [h[3] h[1]    0]
-            [h[4] h[2]  h[]]
-            [h[5] h[3] h[1]]
-            sage: s = SFASchur(QQ)
-            sage: h = SFAHomogeneous(QQ)
-            sage: h( s(part) )
-            h[3, 2, 1] - h[3, 3] - h[4, 1, 1] + h[5, 1]
-            sage: jt.det()
-            h[3, 2, 1] - h[3, 3] - h[4, 1, 1] + h[5, 1]
-        """
-        return sage.combinat.skew_partition.SkewPartition([ self, [] ]).jacobi_trudy()
-    
-##################################################
-
-
-##################
-# Set Partitions #
-##################
-
-def partitions_set(S,k=None):
-    r"""
-
-    WARNING: Wraps GAP -- hence S must be a list of objects that have
-    string representations that can be interpreted by the GAP
-    intepreter.  If mset consists of at all complicated SAGE objects,
-    this function does *not* do what you expect.  A proper function
-    should be written! (TODO!)
-
-    Wraps GAP's PartitionsSet.
-        
-
-    """
-    if k==None:
-        ans=gap.eval("PartitionsSet(%s)"%S)
-    else:
-        ans=gap.eval("PartitionsSet(%s,%s)"%(S,k))
-    return eval(ans)
-
-def number_of_partitions_set(S,k):
-    r"""
-    Returns the size of \code{partitions_set(S,k)}.  Wraps GAP's
-    NrPartitionsSet.
-    
-    The Stirling number of the second kind is the number of partitions
-    of a set of size n into k blocks.
-
-    EXAMPLES:
-        sage: mset = [1,2,3,4]
-        sage: partition.number_of_partitions_set(mset,2)
-        7
-        sage: stirling_number2(4,2)
-        7
-
-    REFERENCES:
-        http://en.wikipedia.org/wiki/Partition_of_a_set
-
-    """
-    if k==None:
-        ans=gap.eval("NrPartitionsSet(%s)"%S)
-    else:
-        ans=gap.eval("NrPartitionsSet(%s,%s)"%(S,ZZ(k)))
-    return ZZ(ans)
-
-def number_of_partitions_list(n,k=None):
-    r"""
-    Returns the size of partitions_list(n,k).
-
-    Wraps GAP's NrPartitions.
- 
-    It is possible to associate with every partition of the integer n
-    a conjugacy class of permutations in the symmetric group on n
-    points and vice versa.  Therefore p(n) = NrPartitions(n) is the
-    number of conjugacy classes of the symmetric group on n points.
-
-    \code{number_of_partitions(n)} is also available in PARI, however
-    the speed seems the same until $n$ is in the thousands (in which
-    case PARI is faster).
-
-    EXAMPLES:
-        sage: partition.number_of_partitions_list(10,2)
-        5
-        sage: partition.number_of_partitions_list(10)
-        42
-
-    A generating function for p(n) is given by the reciprocal of Euler's function:
-    \[
-    \sum_{n=0}^\infty p(n)x^n = \prod_{k=1}^\infty \left(\frac {1}{1-x^k} \right). 
-    \]
-    SAGE verifies that the first several coefficients do instead agree:
-    
-        sage: q = PowerSeriesRing(QQ, 'q', default_prec=9).gen()
-        sage: prod([(1-q^k)^(-1) for k in range(1,9)])  ## partial product of 
-        1 + q + 2*q^2 + 3*q^3 + 5*q^4 + 7*q^5 + 11*q^6 + 15*q^7 + 22*q^8 + O(q^9)
-        sage: [partition.number_of_partitions_list(k) for k in range(2,10)]
-        [2, 3, 5, 7, 11, 15, 22, 30]
-
-    REFERENCES:
-        http://en.wikipedia.org/wiki/Partition_%28number_theory%29
-
-    """
-    if k==None:
-        ans=gap.eval("NrPartitions(%s)"%(ZZ(n)))
-    else:
-        ans=gap.eval("NrPartitions(%s,%s)"%(ZZ(n),ZZ(k)))
-    return ZZ(ans)
-
-
-######################
-# Ordered Partitions #
-######################
-def OrderedPartitions(n, k=None):
-    return OrderedPartitions_nk(n,k)
-
-class OrderedPartitions_nk(CombinatorialClass):
-    def __init__(self, n, k=None):
-        self.n = n
-        self.k = k
-
-    def __repr__(self):
-        string = "Ordered partitions of %s "%self.n
-        if self.k != None:
-            string += "of length %s"%self.k
-        return string
-        
-    def list(self):
-        n = self.n
-        k = self.k
-        if self.k==None:
-            ans=gap.eval("OrderedPartitions(%s)"%(ZZ(n)))
-        else:
-            ans=gap.eval("OrderedPartitions(%s,%s)"%(ZZ(n),ZZ(k)))
-        result = eval(ans.replace('\n',''))
-        result.reverse()
-        return result
-
-    def count(self):
-        n = self.n
-        k = self.k
-        if k==None:
-            ans=gap.eval("NrOrderedPartitions(%s)"%(n))
-        else:
-            ans=gap.eval("NrOrderedPartitions(%s,%s)"%(n,k))
-        return ZZ(ans)
-    
-def ordered_partitions(n,k=None):
-    r"""
-    An {\it ordered partition of $n$} is an ordered sum
-    $$
-       n = p_1+p_2 + \cdots + p_k
-    $$
-    of positive integers and is represented by the list $p = [p_1,p_2,\cdots ,p_k]$.
-    If $k$ is omitted then all ordered partitions are returned.
-
-    \code{ordered_partitions(n,k)} returns the set of all (ordered)
-    partitions of the positive integer n into sums with k summands.
-
-    Do not call \code{ordered_partitions} with an n much larger than
-    15, since the list will simply become too large.
-
-    Wraps GAP's OrderedPartitions.
-        
-    The number of ordered partitions $T_n$ of $\{ 1, 2, ..., n \}$ has the 
-    generating function is
-    \[
-    \sum_n {T_n \over n!} x^n = {1 \over 2-e^x}. 
-    \]
-
-    EXAMPLES:
-        sage: partition.ordered_partitions(10,2)
-        [[1, 9], [2, 8], [3, 7], [4, 6], [5, 5], [6, 4], [7, 3], [8, 2], [9, 1]]
-        
-        sage: partition.ordered_partitions(4)
-        [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]]
-
-    REFERENCES:
-        http://en.wikipedia.org/wiki/Ordered_partition_of_a_set
-
-    """
-    if k==None:
-        ans=gap.eval("OrderedPartitions(%s)"%(ZZ(n)))
-    else:
-        ans=gap.eval("OrderedPartitions(%s,%s)"%(ZZ(n),ZZ(k)))
-    result = eval(ans.replace('\n',''))
-    return [Partition(p) for p in result]
-
-def number_of_ordered_partitions(n,k=None):
-    """
-    Returns the size of ordered_partitions(n,k).
-    Wraps GAP's NrOrderedPartitions.
- 
-    It is possible to associate with every partition of the integer n a conjugacy 
-    class of permutations in the symmetric group on n points and vice versa. 
-    Therefore p(n) = NrPartitions(n) is the number of conjugacy classes of the 
-    symmetric group on n points.
-
-   
-    EXAMPLES:
-        sage: partition.number_of_ordered_partitions(10,2)
-        9
-        sage: partition.number_of_ordered_partitions(15)
-        16384
-    """
-    if k==None:
-        ans=gap.eval("NrOrderedPartitions(%s)"%(n))
-    else:
-        ans=gap.eval("NrOrderedPartitions(%s,%s)"%(n,k))
-    return ZZ(ans)
-
-##########################
-# Partitions Greatest LE #
-##########################
-def PartitionsGreatestLE(n,k):
-    return PartitionsGreatestLE_nk(n,k)
-
-class PartitionsGreatestLE_nk(CombinatorialClass):
-    """
-    The combinatorial class of all (unordered) ``restricted'' partitions of the
-    integer n having parts less than or equal to the integer k.
-    """
-    object_class = Partition_class
-    def __init__(self, n, k):
-        self.n = n
-        self.k = k
-        
-    def __repr__(self):
-        return "Partitions of %s having parts less than or equal to %s"%(self.n, self.k)
-
-    def list(self):
-        """
-        Returns a list of all (unordered) ``restricted'' partitions of the
-        integer n having parts less than or equal to the integer k.
-    
-        Wraps GAP's PartitionsGreatestLE.
-
-        EXAMPLES:
-            sage: PartitionsGreatestLE(10,2).list()
-            [[2, 2, 2, 2, 2],
-             [2, 2, 2, 2, 1, 1],
-             [2, 2, 2, 1, 1, 1, 1],
-             [2, 2, 1, 1, 1, 1, 1, 1],
-             [2, 1, 1, 1, 1, 1, 1, 1, 1],
-             [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
-        """
-        result = eval(gap.eval("PartitionsGreatestLE(%s,%s)"%(ZZ(self.n),ZZ(self.k))))
-        result.reverse()
-        return [Partition(p) for p in result]        
-
-##########################
-# Partitions Greatest EQ #
-##########################
-def PartitionsGreatestEQ(n,k):
-    return PartitionsGreatestEQ_nk(n,k)
-
-class PartitionsGreatestEQ_nk(CombinatorialClass):
-    """
-    The combinatorial class of all (unordered) ``restricted'' partitions of the 
-    integer n having at least one part equal to the integer k.
-    """
-    object_class = Partition_class
-    def __init__(self, n, k):
-        self.n = n
-        self.k = k
-        
-    def __repr__(self):
-        return "Partitions of %s having at least one part equal to %s"%(self.n, self.k)
-    
-    def list(self):
-        """
-        Returns a list of all (unordered) ``restricted'' partitions of the 
-        integer n having at least one part equal to the integer k.
-
-        Wraps GAP's PartitionsGreatestEQ.
-
-        EXAMPLES:
-           sage: PartitionsGreatestEQ(10,2).list()
-           [[2, 2, 2, 2, 2],
-            [2, 2, 2, 2, 1, 1],
-            [2, 2, 2, 1, 1, 1, 1],
-            [2, 2, 1, 1, 1, 1, 1, 1],
-            [2, 1, 1, 1, 1, 1, 1, 1, 1]]
-        """
-        result = eval(gap.eval("PartitionsGreatestEQ(%s,%s)"%(self.n,self.k)))
-        result.reverse()
-        return [Partition(p) for p in result]
-
-
-#########################
-# Restricted Partitions #
-#########################
-def RestrictedPartitions(n, S, k=None):
-    return RestrictedPartitions_nsk(n, S, k)
-
-class RestrictedPartitions(CombinatorialClass):
-    r"""
-    A {\it restricted partition} is, like an ordinary partition, 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. The difference is that here the $p_i$ must be elements 
-    from the set $S$, while for ordinary partitions they may be 
-    elements from $[1..n]$.
-
-    """
-    object_class = Partition_class
-    def __init__(self, n, S, k=None):
-        self.n = n
-        self.S = S
-        self.S.sort()
-        self.k = k
-
-    def __repr__(self):
-        string = "Partitions of %s restricted to the values %s "%(self.n, self.S)
-        if self.k != None:
-            string += "of length %s" % self.k
-        return string
-
-    def list(self):
-        r"""
-        Returns the set of all restricted partitions of the positive integer 
-        n into sums with k summands with the summands of the partition coming 
-        from the set $S$. If k is not given all restricted partitions for all 
-        k are returned.
-        
-        Wraps GAP's RestrictedPartitions.
-
-        EXAMPLES:
-            sage: RestrictedPartitions(8,[1,3,5,7]).list()
-            [[7, 1],
-            [5, 3],
-            [5, 1, 1, 1],
-            [3, 3, 1, 1],
-            [3, 1, 1, 1, 1, 1],
-            [1, 1, 1, 1, 1, 1, 1, 1]]
-            sage: RestrictedPartitions(8,[1,3,5,7],2).list()
-            [[7, 1], [5, 3]]
-        """
-        n = self.n
-        k = self.k
-        S = self.S
-        if k==None:
-            ans=gap.eval("RestrictedPartitions(%s,%s)"%(n,S))
-        else:
-            ans=gap.eval("RestrictedPartitions(%s,%s,%s)"%(n,S,k))
-        result = eval(ans)
-        result.reverse()
-        return [Partition(p) for p in result]
-
-    def count(self):
-        """
-        Returns the size of RestrictedPartitions(n,S,k).
-        Wraps GAP's NrRestrictedPartitions.
-        
-        EXAMPLES:
-            sage: RestrictedPartitions(8,[1,3,5,7]).count()
-            6
-            sage: RestrictedPartitions(8,[1,3,5,7],2).count()
-            2
-        """
-        n = self.n
-        k = self.k
-        S = self.S
-        if k==None:
-            ans=gap.eval("NrRestrictedPartitions(%s,%s)"%(ZZ(n),S))
-        else:
-            ans=gap.eval("NrRestrictedPartitions(%s,%s,%s)"%(ZZ(n),S,ZZ(k)))
-        return ZZ(ans)
-        
-####################
-# Partition Tuples #
-####################
-def PartitionTuples(n,k):
-    return PartitionTuples_nk(n,k)
-
-class PartitionTuples_nk(CombinatorialClass):
-    """
-    k-tuples of partitions describe the classes and the characters of 
-    wreath products of groups with k conjugacy classes with the symmetric 
-    group $S_n$.
-    
-    """
-    object_class = Partition_class
-    def __init__(self, n, k):
-        self.n = n
-        self.k = k
-        
-    def __repr__(self):
-        return "%s-tuples of partitions of %s"%(self.k, self.n)
-
-    def list(self):
-        """
-        Returns the list of all k-tuples of partitions 
-        which together form a partition of n. 
-        
-        Wraps GAP's PartitionTuples.
-
-        EXAMPLES:
-            sage: PartitionTuples(3,2).list()
-            [[[1, 1, 1], []],
-            [[1, 1], [1]],
-            [[1], [1, 1]],
-            [[], [1, 1, 1]],
-            [[2, 1], []],
-            [[1], [2]],
-            [[2], [1]],
-            [[], [2, 1]],
-            [[3], []],
-            [[], [3]]]
-        """
-        ans=gap.eval("PartitionTuples(%s,%s)"%(ZZ(self.n),ZZ(self.k)))
-        return map(lambda x: map(lambda y: Partition(y), x), eval(ans))
-    
-    def count(self):
-        r"""
-        Returns the number of k-tuples of partitions which together
-        form a partition of n.
-        
-        Wraps GAP's NrPartitionTuples.
-
-        EXAMPLES:
-            sage: PartitionTuples(3,2).count()
-            10
-            sage: PartitionTuples(8,2).count()
-            185
-            
-            Now we compare that with the result of the following GAP
-            computation:
-            \begin{verbatim}
-            gap> S8:=Group((1,2,3,4,5,6,7,8),(1,2));
-            Group([ (1,2,3,4,5,6,7,8), (1,2) ])
-            gap> C2:=Group((1,2));
-            Group([ (1,2) ])
-            gap> W:=WreathProduct(C2,S8);
-            <permutation group of size 10321920 with 10 generators>
-            gap> Size(W);
-            10321920     ## = 2^8*Factorial(8), which is good:-)
-            gap> Size(ConjugacyClasses(W));
-            185
-            \end{verbatim}          
-        """
-        
-        ans=gap.eval("NrPartitionTuples(%s,%s)"%(ZZ(self.n),ZZ(self.k)))
-        return ZZ(ans)
-
-##############
-# Partitions #
-##############
-
-def Partitions(n=None, **kwargs):
-    if n == None:
-        return Partitions_all()
-    else:
-        if len(kwargs) == 0:
-            return Partitions_n(n)
-        else:
-            return Partitions_constraints(n, **kwargs)
-
-class Partitions_all(CombinatorialClass):
-    object_class = Partition_class
-    def __contains__(self, x):
-        if isinstance(x, Partition_class):
-            return True
-        elif isinstance(x, __builtin__.list):
-            for i in range(len(x)):
-                if not isinstance(x[i], (int, Integer)):
-                    return False
-                if x[i] < 0:
-                    return False
-                if i == 0:
-                    prev = x[i]
-                    continue
-                if x[i] > prev:
-                    return False
-                prev = x[i]
-            return True
-        else:
-            return False
-                        
-    def list(self):
-        raise NotImplementedError
-
-class Partitions_constraints(CombinatorialClass):
-    def __init__(self, n, **kwargs):
-        self.n = n
-        self.constraints = kwargs
-
-    def __contains__(self, x):
-        return x in Partitions_all() and sum(x)==self.n and misc.check_integer_list_constraints(x, singleton=True, **self.constraints)
-
-    def size(self):
-        return self.n
-
-    def __repr__(self):
-        return "Partitions of the integer %s satisfying constraints"%self.n
-
-    def iterator(self):
-        """
-        An iterator a list of the partitions of n.
-
-        EXAMPLES:
-            sage: [x for x in Partitions(4)]
-            [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]]
-            sage: [x for x in Partitions(4, length=2)]
-            [[3, 1], [2, 2]]
-            sage: [x for x in Partitions(4, min_length=2)]
-            [[3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]]
-            sage: [x for x in Partitions(4, max_length=2)]
-            [[4], [3, 1], [2, 2]]
-            sage: [x for x in Partitions(4, min_length=2, max_length=2)]
-            [[3, 1], [2, 2]]
-            sage: [x for x in Partitions(4, max_part=2)]
-            [[2, 2], [2, 1, 1], [1, 1, 1, 1]]
-            sage: [x for x in Partitions(4, min_part=2)]
-            [[4], [2, 2]]
-            sage: [x for x in Partitions(4, length=3, min_part=0)]
-            [[4, 0, 0], [3, 1, 0], [2, 2, 0], [2, 1, 1]]
-            sage: [x for x in Partitions(4, min_length=3, min_part=0)]
-            [[4, 0, 0], [3, 1, 0], [2, 2, 0], [2, 1, 1], [1, 1, 1, 1]]
-            sage: [x for x in Partitions(4, outer=[3,1,1])]
-            [[3, 1], [2, 1, 1]]
-            sage: [x for x in Partitions(4, outer=['inf', 1, 1])]
-            [[4], [3, 1], [2, 1, 1]]
-            sage: [x for x in Partitions(4, inner=[1,1,1])]
-            [[2, 1, 1], [1, 1, 1, 1]]
-            sage: [x for x in Partitions(4, max_slope=-1)]
-            [[4], [3, 1]]
-            sage: [x for x in Partitions(4, min_slope=-1)]
-            [[4], [2, 2], [2, 1, 1], [1, 1, 1, 1]]
-            sage: [x for x in Partitions(11, max_slope=-1, min_slope=-3, min_length=2, max_length=4)]
-            [[7, 4], [6, 5], [6, 4, 1], [6, 3, 2], [5, 4, 2], [5, 3, 2, 1]]
-            sage: [x for x in Partitions(11, max_slope=-1, min_slope=-3, min_length=2, max_length=4, outer=[6,5,2])]
-            [[6, 5], [6, 4, 1], [6, 3, 2], [5, 4, 2]]
-        """
-        n = self.n
-
-        #put the constraints in the namespace
-        length = self.constraints.get('length',None)
-        min_length = self.constraints.get('min_length',None)
-        max_length = self.constraints.get('max_length',None)        
-        max_part = self.constraints.get('max_part',None)
-        min_part = self.constraints.get('min_part',None)
-        max_slope = self.constraints.get('max_slope',None)
-        min_slope = self.constraints.get('min_slope',None)
-        inner = self.constraints.get('inner',None)
-        outer = self.constraints.get('outer',None)
-
-        #Preproccess the constraints
-        if max_slope == "inf":
-            max_slope = n
-        if min_slope == "-inf":
-            min_slope = -n
-        if length != None:
-            min_length = length
-            max_length = length
-        if outer != None:
-            for i in range(len(outer)):
-                if outer[i] == "inf":
-                    outer[i] = n
-
-        l = []
-        old_p = Partition_class([self.n])
-
-        #Go through all of the partitions
-        while old_p != False:
-            meets_constraints = True
-
-            #Handle the case if the user specifies
-            #min_part = 0
-            if min_part == 0:
-                #if length != None and len(p) < length:
-                #    p += [0]*(len(p)-length)
-                if min_length != None and len(old_p) < min_length:
-                    p = old_p + [0]*(min_length-len(old_p))
-                else:
-                    p = old_p
-            else:
-                p = old_p
-
-            #if length != None:
-            #    if len(p) != length:
-            #        meets_constraints = False
-
-            if min_length != None:
-                if len(p) < min_length:
-                    meets_constraints = False
-
-            if max_length != None:
-                if len(p) > max_length:
-                    meets_constraints = False
-
-            if max_part != None:
-                if max(p) > max_part:
-                    meets_constraints = False
-
-            if min_part != None:
-                if min(p) < min_part:
-                    meets_constraints = False
-
-            if outer != None:
-                if len(p) > len(outer):
-                    meets_constraints = False
-                else:
-                    for i in range(len(p)):
-                        if p[i] > outer[i]:
-                            meets_constraints = False
-
-            if inner != None:
-                if len(p) < len(inner):
-                    meets_constraints = False
-                else:
-                    for i in range(len(inner)):
-                        if p[i] < inner[i]:
-                            meets_constraints = False
-
-
-            if max_slope != None:
-                if max([p[i+1]-p[i] for i in range(0, len(p)-1)]+[-n] ) > max_slope:
-                    meets_constraints = False
-
-            if min_slope != None:
-                if min([p[i+1]-p[i] for i in range(0, len(p)-1)]+[n] ) < min_slope:
-                    meets_constraints = False
-
-
-            if meets_constraints:
-                yield p
-
-            old_p = old_p.next()
-
-class Partitions_n(CombinatorialClass):
-    object_class = Partition_class
-    def __init__(self, n):
-        self.n = n
-
-    def __contains__(self, x):
-        return x in Partitions_all() and sum(x)==self.n
-
-    def size(self):
-        return self.n
-
-    def __repr__(self):
-        return "Partitions of the integer %s"%self.n
-
-    def count(self, algorithm='default'):
-        r"""
-            algorithm -- (default: 'default')
-                'bober' -- use Jonathon Bober's implementation (*very* fast,
-                          but new and not well tested yet).
-                'gap' -- use GAP (VERY *slow*)
-                'pari' -- use PARI.  Speed seems the same as GAP until $n$ is
-                          in the thousands, in which case PARI is faster. *But*
-                          PARI has a bug, e.g., on 64-bit Linux PARI-2.3.2
-                          outputs numbpart(147007)%1000 as 536, but it
-                          should be 533!.  So do not use this option.
-                'default' -- 'bober' when k is not specified; otherwise
-                          use 'gap'.
-
-        IMPLEMENTATION: Wraps GAP's NrPartitions or PARI's numbpart function.
-
-        Use the function \code{partitions(n)} to return a generator over
-        all partitions of $n$.
-
-        It is possible to associate with every partition of the integer n
-        a conjugacy class of permutations in the symmetric group on n
-        points and vice versa.  Therefore p(n) = NrPartitions(n) is the
-        number of conjugacy classes of the symmetric group on n points.
-
-        EXAMPLES:
-            sage: v = Partitions(5).list(); v
-            [[5], [4, 1], [3, 2], [3, 1, 1], [2, 2, 1], [2, 1, 1, 1], [1, 1, 1, 1, 1]]
-            sage: len(v)
-            7
-            sage: Partitions(5).count(algorithm='gap')
-            7
-            sage: Partitions(5).count(algorithm='pari')
-            7
-            sage: Partitions(5).count(algorithm='bober')
-            7
-
-        The input must be a nonnegative integer or a ValueError is raised.
-            sage: Partitions(10).count()
-            42
-            sage: Partitions(3).count()
-            3
-            sage: Partitions(10).count()
-            42
-            sage: Partitions(3).count(algorithm='pari')
-            3
-            sage: Partitions(10).count(algorithm='pari')
-            42
-            sage: Partitions(40).count()
-            37338
-            sage: Partitions(100).count()
-            190569292
-
-        A generating function for p(n) is given by the reciprocal of
-        Euler's function:
-
-        \[
-        \sum_{n=0}^\infty p(n)x^n = \prod_{k=1}^\infty \left(\frac {1}{1-x^k} \right). 
-        \]
-
-        We use SAGE to verify that the first several coefficients do
-        instead agree:
-
-            sage: q = PowerSeriesRing(QQ, 'q', default_prec=9).gen()
-            sage: prod([(1-q^k)^(-1) for k in range(1,9)])  ## partial product of 
-            1 + q + 2*q^2 + 3*q^3 + 5*q^4 + 7*q^5 + 11*q^6 + 15*q^7 + 22*q^8 + O(q^9)
-            sage: [Partitions(k) .count()for k in range(2,10)]
-            [2, 3, 5, 7, 11, 15, 22, 30]
-
-        REFERENCES:
-            http://en.wikipedia.org/wiki/Partition_%28number_theory%29
-
-        """
-        n = ZZ(self.n)
-        if n < 0:
-            raise ValueError, "n (=%s) must be a nonnegative integer"%n
-        elif n == 0:
-            return ZZ(1)
-        if algorithm == 'gap':
-            ans=gap.eval("NrPartitions(%s)"%(n))
-            return ZZ(ans)
-        if algorithm == 'default':
-            return partitions_ext.number_of_partitions(n)
-        elif algorithm == 'bober':
-            return partitions_ext.number_of_partitions(n)
-        elif algorithm == 'pari':
-            return ZZ(pari(n).numbpart())
-        raise ValueError, "unknown algorithm '%s'"%algorithm
-
-    def first(self):
-        """
-        Returns the lexicographically first partition of a
-        positive integer n. This is the partition [n].
-
-        EXAMPLES:
-            sage: Partitions(4).first()
-            [4]
-        """
-        return Partition([self.n])
-
-    def last(self):
-        """
-        Returns the lexicographically last partition of the
-        positive integer n.  This is the all-ones partition.
-
-        EXAMPLES:
-            sage: Partitions(4).last()
-            [1, 1, 1, 1]
-        """
-
-        return Partition_class([1]*self.n)
-
-
-    def iterator(self):
-        """
-        An iterator a list of the partitions of n.
-
-        EXAMPLES:
-            sage: [x for x in Partitions(4)]
-            [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]]
-        """
-        # base case of the recursion: zero is the sum of the empty tuple
-        if n == 0:
-            yield []
-            return
-        
-        # modify the partitions of n-1 to form the partitions of n
-        for p in Partitions_n(self.n-1):
-            if p and (len(p) < 2 or p[-2] > p[-1]):
-                yield p[:-1] + [p[-1] + 1]
-            yield  p + [1]
-
-
-
-def PartitionsInBox(h, w):
-    return PartitionsInBox_hw(h, w)
-
-class PartitionsInBox_hw(CombinatorialClass):
-    object_class = Partition_class
-    def __init__(self, h, w):
-        self.h = h
-        self.w = w
-
-    def __repr__(self):
-        return "Integer Partitions which fit in a %s x %s box" % (self.h, self.w)
-
-    def list(self):
-        """
-        Returns a list of all the partitions inside a box of height h
-        and width w.
-
-        EXAMPLES:
-            sage: PartitionsInBox(2,2).list()
-            [[], [1], [1, 1], [2], [2, 1], [2, 2]]
-        """
-        h = self.h
-        w = self.w
-        if h == 0:
-            return [[]]
-        else:
-            l = [[i] for i in range(0, w+1)]
-            add = lambda x: [ x+[i] for i in range(0, x[-1]+1)]
-            for i in range(h-1):
-                new_list = []
-                for element in l:
-                    new_list += add(element)
-                l = new_list
-
-            return [Partition(filter(lambda x: x!=0, p)) for p in l]
Index: age/combinat/partition_algebra.py
===================================================================
--- sage/combinat/partition_algebra.py	(revision 6439)
+++ 	(revision )
@@ -1,1320 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 combinat import CombinatorialClass, CombinatorialObject, catalan_number
-from combinatorial_algebra import CombinatorialAlgebra, CombinatorialAlgebraElement
-import set_partition
-from sage.sets.set import Set
-from sage.graphs.graph import Graph
-from sage.rings.arith import factorial
-from permutation import Permutations
-from sage.rings.all import Integer, is_RealNumber
-from sage.calculus.all import floor, ceil
-
-
-def create_set_partitions_function(letter):
-    """
-    """
-    def function(k):
-        """
-        """
-        if isinstance(k, (int, Integer)):
-            if k > 0:
-                return eval('SetPartitions' + letter + 'k_k(k)')
-        elif is_RealNumber(k):
-            if k - floor(k) == 0.5:
-                return eval('SetPartitions' + letter + 'khalf_k(floor(k))')
-
-        raise ValueError, "k must be an integer or an integer + 1/2"
-
-    return function
-
-#####
-#A_k#
-#####
-SetPartitionsAk = create_set_partitions_function("A")
-SetPartitionsAk.__doc__ = """
-Returns the combinatorial class of set partitions of type A_k.
-
-EXAMPLES:
-    sage: A3 = SetPartitionsAk(3); A3
-    Set partitions of {1, ..., 3, -1, ..., -3}
-
-    sage: A3.first() #random
-    {{1, 2, 3, -1, -3, -2}}
-    sage: A3.last() #random
-    {{-1}, {-2}, {3}, {1}, {-3}, {2}}
-    sage: A3.random()  #random
-    {{1, 3, -3, -1}, {2, -2}}
-
-    sage: A3.count()
-    203
-
-    sage: A2p5 = SetPartitionsAk(2.5); A2p5
-    Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block
-    sage: A2p5.count()
-    52
-
-    sage: A2p5.first() #random
-    {{1, 2, 3, -1, -3, -2}}
-    sage: A2p5.last() #random
-    {{-1}, {-2}, {2}, {3, -3}, {1}}
-    sage: A2p5.random() #random
-    {{-1}, {-2}, {3, -3}, {1, 2}}
-    
-"""
-
-class SetPartitionsAk_k(set_partition.SetPartitions_set):
-    def __init__(self, k):
-        """
-        TESTS:
-           sage: A3 = SetPartitionsAk(3); A3
-           Set partitions of {1, ..., 3, -1, ..., -3}
-           sage: A3 == loads(dumps(A3))
-           True
-        """
-        self.k = k
-        set_partition.SetPartitions_set.__init__(self, Set(range(1,k+1) + map(lambda x: -1*x,range(1,k+1))))
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitionsAk(3))
-            'Set partitions of {1, ..., 3, -1, ..., -3}'
-        """
-        return "Set partitions of {1, ..., %s, -1, ..., -%s}"%(self.k, self.k)
-
-class SetPartitionsAkhalf_k(CombinatorialClass):
-    def __init__(self, k):
-        """
-        TESTS:
-            sage: A2p5 = SetPartitionsAk(2.5); A2p5
-            Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block
-            sage: A2p5 == loads(dumps(A2p5))
-            True           
-        """
-        self.k = k
-        self._set = range(1,k+2) + map(lambda x: -1*x, range(1,k+1))
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitionsAk(2.5))
-            'Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block'
-        """
-        s = self.k+1
-        return "Set partitions of {1, ..., %s, -1, ..., -%s} with %s and -%s in the same block"%(s,s,s,s)
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: A2p5 = SetPartitionsAk(2.5)
-            sage: all([ sp in A2p5 for sp in A2p5])
-            True
-            sage: A3 = SetPartitionsAk(3)
-            sage: len(filter(lambda x: x in A2p5, A3))
-            52
-            sage: A2p5.count()
-            52
-        """
-        if x not in SetPartitionsAk_k(self.k+1):
-            return False
-
-        for part in x:
-            if self.k+1 in part and -self.k-1 not in part:
-                return False
-
-        return True
-
-    def count(self):
-        """
-        TESTS:
-            sage: SetPartitionsAk(1.5).count()
-            5
-            sage: SetPartitionsAk(2.5).count()
-            52
-            sage: SetPartitionsAk(3.5).count()
-            877
-        """
-        return set_partition.SetPartitions_set(self._set).count()
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: SetPartitionsAk(1.5).list() #random
-            [{{1, 2, -2, -1}},
-             {{2, -2, -1}, {1}},
-             {{2, -2}, {1, -1}},
-             {{-1}, {1, 2, -2}},
-             {{-1}, {2, -2}, {1}}]
-
-             sage: ks = [ 1.5, 2.5, 3.5 ]
-             sage: aks = map(SetPartitionsAk, ks)
-             sage: all([ak.count() == len(ak.list()) for ak in aks])
-             True
-        """
-        kp = Set([-self.k-1])
-        for sp in set_partition.SetPartitions_set(self._set):
-            res = []
-            for part in sp:
-                if self.k+1 in part:
-                    res.append( part + kp )
-                else:
-                    res.append(part)
-            yield Set(res)
-
-#####
-#S_k#
-#####
-SetPartitionsSk = create_set_partitions_function("S")
-SetPartitionsSk.__doc__ = """
-Returns the combinatorial class of set partitions of type S_k.  There
-is a bijection between these set partitions and the permutations
-of 1, ..., k.
-
-EXAMPLES:
-    sage: S3 = SetPartitionsSk(3); S3
-    Set partitions of {1, ..., 3, -1, ..., -3} with propagating number 3
-    sage: S3.count()
-    6
-
-    sage: S3.list()  #random
-    [{{2, -2}, {3, -3}, {1, -1}},
-     {{1, -1}, {2, -3}, {3, -2}},
-     {{2, -1}, {3, -3}, {1, -2}},
-     {{1, -2}, {2, -3}, {3, -1}},
-     {{1, -3}, {2, -1}, {3, -2}},
-     {{1, -3}, {2, -2}, {3, -1}}]
-    sage: S3.first() #random
-    {{2, -2}, {3, -3}, {1, -1}}
-    sage: S3.last() #random
-    {{1, -3}, {2, -2}, {3, -1}}
-    sage: S3.random() #random
-    {{1, -3}, {2, -1}, {3, -2}}
-
-    sage: S3p5 = SetPartitionsSk(3.5); S3p5
-    Set partitions of {1, ..., 4, -1, ..., -4} with 4 and -4 in the same block and propagating number 4
-    sage: S3p5.count()
-    6
-
-    sage: S3p5.list() #random
-    [{{2, -2}, {3, -3}, {1, -1}, {4, -4}},
-     {{2, -3}, {1, -1}, {4, -4}, {3, -2}},
-     {{2, -1}, {3, -3}, {1, -2}, {4, -4}},
-     {{2, -3}, {1, -2}, {4, -4}, {3, -1}},
-     {{1, -3}, {2, -1}, {4, -4}, {3, -2}},
-     {{1, -3}, {2, -2}, {4, -4}, {3, -1}}]
-    sage: S3p5.first() #random
-    {{2, -2}, {3, -3}, {1, -1}, {4, -4}}
-    sage: S3p5.last() #random
-    {{1, -3}, {2, -2}, {4, -4}, {3, -1}}
-    sage: S3p5.random() #random
-    {{1, -3}, {2, -2}, {4, -4}, {3, -1}}
-"""
-class SetPartitionsSk_k(SetPartitionsAk_k):
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitionsSk(3))
-            'Set partitions of {1, ..., 3, -1, ..., -3} with propagating number 3'
-        """
-        return SetPartitionsAk_k.__repr__(self) + " with propagating number %s"%self.k
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: A3 = SetPartitionsAk(3)
-            sage: S3 = SetPartitionsSk(3)
-            sage: all([ sp in S3 for sp in S3])
-            True
-            sage: S3.count()
-            6
-            sage: len(filter(lambda x: x in S3, A3))
-            6
-        """
-        if not SetPartitionsAk_k.__contains__(self, x):
-            return False
-
-        if propagating_number(x) != self.k:
-            return False
-
-        return True
-
-    def count(self):
-        """
-        Returns k!.
-        
-        TESTS:
-            sage: SetPartitionsSk(2).count()
-            2
-            sage: SetPartitionsSk(3).count()
-            6
-            sage: SetPartitionsSk(4).count()
-            24
-            sage: SetPartitionsSk(5).count()
-            120
-        """
-        return factorial(self.k)
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: SetPartitionsSk(3).list() #random
-            [{{2, -2}, {3, -3}, {1, -1}},
-             {{1, -1}, {2, -3}, {3, -2}},
-             {{2, -1}, {3, -3}, {1, -2}},
-             {{1, -2}, {2, -3}, {3, -1}},
-             {{1, -3}, {2, -1}, {3, -2}},
-             {{1, -3}, {2, -2}, {3, -1}}]
-            sage: ks = range(1, 6)
-            sage: sks = map(SetPartitionsSk, ks)
-            sage: all([ sk.count() == len(sk.list()) for sk in sks])
-            True
-        """
-        for p in Permutations(self.k):
-            res = []
-            for i in range(self.k):
-                res.append( Set([ i+1, -p[i] ]) )
-            yield Set(res)
-
-class SetPartitionsSkhalf_k(SetPartitionsAkhalf_k):
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: S2p5 = SetPartitionsSk(2.5)
-            sage: A3 = SetPartitionsAk(3)
-            sage: all([sp in S2p5 for sp in S2p5])
-            True
-            sage: len(filter(lambda x: x in S2p5, A3))
-            2
-            sage: S2p5.count()
-            2
-        """
-        if not SetPartitionsAkhalf_k.__contains__(self, x):
-            return False
-        if propagating_number(x) != self.k+1:
-            return False
-        return True
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitionsSk(2.5))
-            'Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block and propagating number 3'
-        """
-        s = self.k+1
-        return SetPartitionsAkhalf_k.__repr__(self) + " and propagating number %s"%s
-
-    def count(self):
-        """
-        TESTS:
-            sage: SetPartitionsSk(2.5).count()
-            2
-            sage: SetPartitionsSk(3.5).count()
-            6
-            sage: SetPartitionsSk(4.5).count()
-            24
-
-            sage: ks = [2.5, 3.5, 4.5, 5.5]
-            sage: sks = [SetPartitionsSk(k) for k in ks]
-            sage: all([ sk.count() == len(sk.list()) for sk in sks])
-            True
-
-        """
-        return factorial(self.k)
-
-    def iterator(self):
-        """
-
-        TESTS:
-            sage: SetPartitionsSk(3.5).list() #random indirect test
-            [{{2, -2}, {3, -3}, {1, -1}, {4, -4}},
-             {{2, -3}, {1, -1}, {4, -4}, {3, -2}},
-             {{2, -1}, {3, -3}, {1, -2}, {4, -4}},
-             {{2, -3}, {1, -2}, {4, -4}, {3, -1}},
-             {{1, -3}, {2, -1}, {4, -4}, {3, -2}},
-             {{1, -3}, {2, -2}, {4, -4}, {3, -1}}]
-        """
-        for p in Permutations(self.k):
-            res = []
-            for i in range(self.k):
-                res.append( Set([ i+1, -p[i] ]) )
-
-            res.append(Set([self.k+1, -self.k - 1]))
-            yield Set(res)
-
-#####
-#I_k#
-#####
-SetPartitionsIk = create_set_partitions_function("I")
-SetPartitionsIk.__doc__ = """
-Returns the combinatorial class of set partitions of type I_k.  These
-are set partitions with a propagating number of less than k.  Note
-that the identity set partition {{1, -1}, ..., {k, -k}} is not
-in I_k.
-
-EXAMPLES:
-    sage: I3 = SetPartitionsIk(3); I3
-    Set partitions of {1, ..., 3, -1, ..., -3} with propagating number < 3
-    sage: I3.count()
-    197
-
-    sage: I3.first() #random
-    {{1, 2, 3, -1, -3, -2}}
-    sage: I3.last() #random
-    {{-1}, {-2}, {3}, {1}, {-3}, {2}}
-    sage: I3.random() #random
-    {{-1}, {-3, -2}, {2, 3}, {1}}
-
-    sage: I2p5 = SetPartitionsIk(2.5); I2p5
-    Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block and propagating number < 3
-    sage: I2p5.count()
-    50
-
-    sage: I2p5.first() #random
-    {{1, 2, 3, -1, -3, -2}}
-    sage: I2p5.last() #random
-    {{-1}, {-2}, {2}, {3, -3}, {1}}
-    sage: I2p5.random() #random
-    {{-1}, {-2}, {1, 3, -3}, {2}}
-
-"""
-class SetPartitionsIk_k(SetPartitionsAk_k):
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitionsIk(3))
-            'Set partitions of {1, ..., 3, -1, ..., -3} with propagating number < 3'
-        """
-        return SetPartitionsAk_k.__repr__(self) + " with propagating number < %s"%self.k
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: I3 = SetPartitionsIk(3)
-            sage: A3 = SetPartitionsAk(3)
-            sage: all([ sp in I3 for sp in I3])
-            True
-            sage: len(filter(lambda x: x in I3, A3))
-            197
-            sage: I3.count()
-            197
-        """
-        if not SetPartitionsAk_k.__contains__(self, x):
-            return False
-        if propagating_number(x) >= self.k:
-            return False
-        return True
-
-    def count(self):
-        """
-        TESTS:
-            sage: SetPartitionsIk(2).count()
-            13
-        """
-        return len(self.list())
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: SetPartitionsIk(2).list() #random indirect test
-                [{{1, 2, -1, -2}},
-                 {{2, -1, -2}, {1}},
-                 {{2}, {1, -1, -2}},
-                 {{-1}, {1, 2, -2}},
-                 {{-2}, {1, 2, -1}},
-                 {{1, 2}, {-1, -2}},
-                 {{2}, {-1, -2}, {1}},
-                 {{-1}, {2, -2}, {1}},
-                 {{-2}, {2, -1}, {1}},
-                 {{-1}, {2}, {1, -2}},
-                 {{-2}, {2}, {1, -1}},
-                 {{-1}, {-2}, {1, 2}},
-                 {{-1}, {-2}, {2}, {1}}]
-        """
-        for sp in SetPartitionsAk_k.iterator(self):
-            if propagating_number(sp) < self.k:
-                yield sp
-
-class SetPartitionsIkhalf_k(SetPartitionsAkhalf_k):
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: I2p5 = SetPartitionsIk(2.5)
-            sage: A3 = SetPartitionsAk(3)
-            sage: all([ sp in I2p5 for sp in I2p5])
-            True
-            sage: len(filter(lambda x: x in I2p5, A3))
-            50
-            sage: I2p5.count()
-            50
-        """
-        if not SetPartitionsAkhalf_k.__contains__(self, x):
-            return False
-        if propagating_number(x) >= self.k+1:
-            return False
-        return True
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitionsIk(2.5))
-            'Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block and propagating number < 3'
-        """
-        return SetPartitionsAkhalf_k.__repr__(self) + " and propagating number < %s"%(self.k+1)
-
-    def count(self):
-        """
-        TESTS:
-            sage: SetPartitionsIk(1.5).count()
-            4
-            sage: SetPartitionsIk(2.5).count()
-            50
-            sage: SetPartitionsIk(3.5).count()
-            871
-        """
-        return len(self.list())
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: SetPartitionsIk(1.5).list() #random
-            [{{1, 2, -2, -1}},
-             {{2, -2, -1}, {1}},
-             {{-1}, {1, 2, -2}},
-             {{-1}, {2, -2}, {1}}]
-        """
-
-        for sp in SetPartitionsAkhalf_k.iterator(self):
-            if propagating_number(sp) < self.k+1:
-                yield sp
-#####
-#B_k#
-#####
-SetPartitionsBk = create_set_partitions_function("B")
-SetPartitionsBk.__doc__ = """
-Returns the combinatorial class of set partitions of type B_k.
-These are the set partitions where every block has size 2.
-
-EXAMPLES:
-    sage: B3 = SetPartitionsBk(3); B3
-    Set partitions of {1, ..., 3, -1, ..., -3} with block size 2
-
-    sage: B3.first() #random
-    {{2, -2}, {1, -3}, {3, -1}}
-    sage: B3.last() #random
-    {{1, 2}, {3, -2}, {-3, -1}}
-    sage: B3.random() #random
-    {{2, -1}, {1, -3}, {3, -2}}
-
-    sage: B3.count()
-    15
-
-    sage: B2p5 = SetPartitionsBk(2.5); B2p5
-    Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block and with block size 2
-
-    sage: B2p5.first() #random
-    {{2, -1}, {3, -3}, {1, -2}}
-    sage: B2p5.last() #random
-    {{1, 2}, {3, -3}, {-1, -2}}
-    sage: B2p5.random() #random
-    {{2, -2}, {3, -3}, {1, -1}}
-
-    sage: B2p5.count()
-    3
-"""
-
-class SetPartitionsBk_k(SetPartitionsAk_k):
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitionsBk(2.5))
-            'Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block and with block size 2'
-        """
-        return SetPartitionsAk_k.__repr__(self) + " with block size 2"
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: B3 = SetPartitionsBk(3)
-            sage: A3 = SetPartitionsAk(3)
-            sage: len(filter(lambda x: x in B3, A3))
-            15
-            sage: B3.count()
-            15
-        """
-        if not SetPartitionsAk_k.__contains__(self, x):
-            return False
-
-        for part in x:
-            if len(part) != 2:
-                return False
-            
-        return True
-
-    def count(self):
-        """
-        Returns the number of set partitions in B_k where k is an integer.
-        This is given by (2k)!! = (2k-1)*(2k-3)*...*5*3*1.
-
-        EXAMPLES:
-            sage: SetPartitionsBk(3).count()
-            15
-            sage: SetPartitionsBk(2).count()
-            3
-            sage: SetPartitionsBk(1).count()
-            1
-            sage: SetPartitionsBk(4).count()
-            105
-            sage: SetPartitionsBk(5).count()
-            945
-
-        """
-        c = 1
-        for i in range(1, 2*self.k,2):
-            c *= i
-        return c
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: SetPartitionsBk(1).list()
-            [{{1, -1}}]
-
-            sage: SetPartitionsBk(2).list() #random
-            [{{2, -1}, {1, -2}}, {{2, -2}, {1, -1}}, {{1, 2}, {-1, -2}}]
-            sage: SetPartitionsBk(3).list() #random
-            [{{2, -2}, {1, -3}, {3, -1}},
-             {{2, -1}, {1, -3}, {3, -2}},
-             {{1, -3}, {2, 3}, {-1, -2}},
-             {{3, -1}, {1, -2}, {2, -3}},
-             {{3, -2}, {1, -1}, {2, -3}},
-             {{1, 3}, {2, -3}, {-1, -2}},
-             {{2, -1}, {3, -3}, {1, -2}},
-             {{2, -2}, {3, -3}, {1, -1}},
-             {{1, 2}, {3, -3}, {-1, -2}},
-             {{-3, -2}, {2, 3}, {1, -1}},
-             {{1, 3}, {-3, -2}, {2, -1}},
-             {{1, 2}, {3, -1}, {-3, -2}},
-             {{-3, -1}, {2, 3}, {1, -2}},
-             {{1, 3}, {-3, -1}, {2, -2}},
-             {{1, 2}, {3, -2}, {-3, -1}}]
-
-          Check to make sure that the number of elements generated
-          is the same as what is given by count()
-          
-            sage: bks = [ SetPartitionsBk(i) for i in range(1, 6) ]
-            sage: all( [ bk.count() == len(bk.list()) for bk in bks] )
-            True
-        """
-        for sp in set_partition.SetPartitions(self.set, [2]*(len(self.set)/2)):
-            yield sp
-
-class SetPartitionsBkhalf_k(SetPartitionsAkhalf_k):
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitionsBk(2.5))
-            'Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block and with block size 2'
-        """
-        return SetPartitionsAkhalf_k.__repr__(self) + " and with block size 2"
-
-    
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: A3 = SetPartitionsAk(3)
-            sage: B2p5 = SetPartitionsBk(2.5)
-            sage: all([ sp in B2p5 for sp in B2p5 ])
-            True
-            sage: len(filter(lambda x: x in B2p5, A3))
-            3
-            sage: B2p5.count()
-            3
-        """
-        if not SetPartitionsAkhalf_k.__contains__(self, x):
-            return False
-        for part in x:
-            if len(part) != 2:
-                return False
-        return True
-
-    def count(self):
-        """
-        TESTS:
-            sage: B3p5 = SetPartitionsBk(3.5)
-            sage: B3p5.count()
-            15
-        """
-        return len(self.list())
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: B3p5 = SetPartitionsBk(3.5)
-            sage: B3p5.count()
-            15
-
-            sage: B3p5.list() #random
-            [{{2, -2}, {1, -3}, {4, -4}, {3, -1}},
-             {{2, -1}, {1, -3}, {4, -4}, {3, -2}},
-             {{1, -3}, {2, 3}, {4, -4}, {-1, -2}},
-             {{2, -3}, {1, -2}, {4, -4}, {3, -1}},
-             {{2, -3}, {1, -1}, {4, -4}, {3, -2}},
-             {{1, 3}, {4, -4}, {2, -3}, {-1, -2}},
-             {{2, -1}, {3, -3}, {1, -2}, {4, -4}},
-             {{2, -2}, {3, -3}, {1, -1}, {4, -4}},
-             {{1, 2}, {3, -3}, {4, -4}, {-1, -2}},
-             {{-3, -2}, {2, 3}, {1, -1}, {4, -4}},
-             {{1, 3}, {-3, -2}, {2, -1}, {4, -4}},
-             {{1, 2}, {-3, -2}, {4, -4}, {3, -1}},
-             {{-3, -1}, {2, 3}, {1, -2}, {4, -4}},
-             {{1, 3}, {-3, -1}, {2, -2}, {4, -4}},
-             {{1, 2}, {-3, -1}, {4, -4}, {3, -2}}]
-        """
-        set = range(1,self.k+1) + map(lambda x: -1*x, range(1,self.k+1))
-        for sp in set_partition.SetPartitions(set, [2]*(len(set)/2) ):
-            yield sp + Set([Set([self.k+1, -self.k -1])])
-
-#####
-#P_k#
-#####
-SetPartitionsPk = create_set_partitions_function("P")
-SetPartitionsPk.__doc__ = """
-Returns the combinatorial class of set partitions of type P_k.
-These are the planar set partitions.
-
-
-sage: P3 = SetPartitionsPk(3); P3
-Set partitions of {1, ..., 3, -1, ..., -3} that are planar
-sage: P3.count()
-132
-
-sage: P3.first() #random
-{{1, 2, 3, -1, -3, -2}} 
-sage: P3.last() #random
-{{-1}, {-2}, {3}, {1}, {-3}, {2}}
-sage: P3.random() #random
-{{1, 2, -1}, {-3}, {3, -2}}
-
-sage: P2p5 = SetPartitionsPk(2.5); P2p5
-Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block and that are planar
-sage: P2p5.count()
-42
-
-sage: P2p5.first() #random
-{{1, 2, 3, -1, -3, -2}}
-sage: P2p5.last() #random
-{{-1}, {-2}, {2}, {3, -3}, {1}}
-sage: P2p5.random() #random
-{{1, 2, 3, -3}, {-1, -2}}
-
-
-"""
-class SetPartitionsPk_k(SetPartitionsAk_k):
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitionsPk(3))
-            'Set partitions of {1, ..., 3, -1, ..., -3} that are planar'
-        """
-        return SetPartitionsAk_k.__repr__(self) + " that are planar"
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: P3 = SetPartitionsPk(3)
-            sage: A3 = SetPartitionsAk(3)
-            sage: len(filter(lambda x: x in P3, A3))
-            132
-            sage: P3.count()
-            132
-            sage: all([sp in P3 for sp in P3])
-            True
-        """
-        if not SetPartitionsAk_k.__contains__(self, x):
-            return False
-
-        if not is_planar(x):
-            return False
-
-        return True
-
-    def count(self):
-        """
-        TESTS:
-            sage: SetPartitionsPk(2).count()
-            14
-            sage: SetPartitionsPk(3).count()
-            132
-            sage: SetPartitionsPk(4).count()
-            1430
-        """
-        return catalan_number(2*self.k)
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: SetPartitionsPk(2).list() #random indirect test
-            [{{1, 2, -1, -2}},
-             {{2, -1, -2}, {1}},
-             {{2}, {1, -1, -2}},
-             {{-1}, {1, 2, -2}},
-             {{-2}, {1, 2, -1}},
-             {{2, -2}, {1, -1}},
-             {{1, 2}, {-1, -2}},
-             {{2}, {-1, -2}, {1}},
-             {{-1}, {2, -2}, {1}},
-             {{-2}, {2, -1}, {1}},
-             {{-1}, {2}, {1, -2}},
-             {{-2}, {2}, {1, -1}},
-             {{-1}, {-2}, {1, 2}},
-             {{-1}, {-2}, {2}, {1}}]
-        """
-        for sp in SetPartitionsAk_k.iterator(self):
-            if is_planar(sp):
-                yield sp
-
-class SetPartitionsPkhalf_k(SetPartitionsAkhalf_k):
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: A3 = SetPartitionsAk(3)
-            sage: P2p5 = SetPartitionsPk(2.5)
-            sage: all([ sp in P2p5 for sp in P2p5 ])
-            True
-            sage: len(filter(lambda x: x in P2p5, A3))
-            42
-            sage: P2p5.count()
-            42
-        """
-        if not SetPartitionsAkhalf_k.__contains__(self, x):
-            return False
-        if not is_planar(x):
-            return False
-        
-        return True
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr( SetPartitionsPk(2.5) )
-            'Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block and that are planar'
-        """
-        return SetPartitionsAkhalf_k.__repr__(self) + " and that are planar"
-
-    def count(self):
-        """
-        TESTS:
-            sage: SetPartitionsPk(2.5).count()
-            42
-            sage: SetPartitionsPk(1.5).count()
-            5
-        """
-        return len(self.list())
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: SetPartitionsPk(1.5).list() #random
-            [{{1, 2, -2, -1}},
-             {{2, -2, -1}, {1}},
-             {{2, -2}, {1, -1}},
-             {{-1}, {1, 2, -2}},
-             {{-1}, {2, -2}, {1}}]
-
-        """
-        for sp in SetPartitionsAkhalf_k.iterator(self):
-            if is_planar(sp):
-                yield sp
-
-
-#####
-#T_k#
-#####
-SetPartitionsTk = create_set_partitions_function("T")
-SetPartitionsTk.__doc__ = """
-Returns the combinatorial class of set partitions of type T_k.
-These are planar set partitions where every block is of size 2.
-
-sage: T3 = SetPartitionsTk(3); T3
-Set partitions of {1, ..., 3, -1, ..., -3} with block size 2 and that are planar
-sage: T3.count()
-5
-
-sage: T3.first() #random
-{{1, -3}, {2, 3}, {-1, -2}}
-sage: T3.last() #random
-{{1, 2}, {3, -1}, {-3, -2}}
-sage: T3.random() #random
-{{1, -3}, {2, 3}, {-1, -2}}
-
-sage: T2p5 = SetPartitionsTk(2.5); T2p5
-Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block and with block size 2 and that are planar
-sage: T2p5.count()
-2
-
-sage: T2p5.first() #random
-{{2, -2}, {3, -3}, {1, -1}}
-sage: T2p5.last() #random
-{{1, 2}, {3, -3}, {-1, -2}}
-
-"""
-class SetPartitionsTk_k(SetPartitionsBk_k):
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitionsTk(3))
-            'Set partitions of {1, ..., 3, -1, ..., -3} with block size 2 and that are planar'
-        """
-        return SetPartitionsBk_k.__repr__(self) + " and that are planar"
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: T3 = SetPartitionsTk(3)
-            sage: A3 = SetPartitionsAk(3)
-            sage: all([ sp in T3 for sp in T3])
-            True
-            sage: len(filter(lambda x: x in T3, A3))
-            5
-            sage: T3.count()
-            5
-        """
-        if not SetPartitionsBk_k.__contains__(self, x):
-            return False
-
-        if not is_planar(x):
-            return False
-
-        return True
-
-    def count(self):
-        """
-        TESTS:
-            sage: SetPartitionsTk(2).count()
-            2
-            sage: SetPartitionsTk(3).count()
-            5
-            sage: SetPartitionsTk(4).count()
-            14
-            sage: SetPartitionsTk(5).count()
-            42
-        """
-        return catalan_number(self.k)
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: SetPartitionsTk(3).list() #random
-            [{{1, -3}, {2, 3}, {-1, -2}},
-             {{2, -2}, {3, -3}, {1, -1}},
-             {{1, 2}, {3, -3}, {-1, -2}},
-             {{-3, -2}, {2, 3}, {1, -1}},
-             {{1, 2}, {3, -1}, {-3, -2}}]
-        """
-        for sp in SetPartitionsBk_k.iterator(self):
-            if is_planar(sp):
-                yield sp
-
-class SetPartitionsTkhalf_k(SetPartitionsBkhalf_k):
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: A3 = SetPartitionsAk(3)
-            sage: T2p5 = SetPartitionsTk(2.5)
-            sage: all([ sp in T2p5 for sp in T2p5 ])
-            True
-            sage: len(filter(lambda x: x in T2p5, A3))
-            2
-            sage: T2p5.count()
-            2
-        """
-        if not SetPartitionsBkhalf_k.__contains__(self, x):
-            return False
-        if not is_planar(x):
-            return False
-        
-        return True
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitionsTk(2.5))
-            'Set partitions of {1, ..., 3, -1, ..., -3} with 3 and -3 in the same block and with block size 2 and that are planar'
-        """
-        return SetPartitionsBkhalf_k.__repr__(self) + " and that are planar"
-
-    def count(self):
-        """
-        TESTS:
-            sage: SetPartitionsTk(2.5).count()
-            2
-            sage: SetPartitionsTk(3.5).count()
-            5
-            sage: SetPartitionsTk(4.5).count()
-            14
-        """
-        return catalan_number(self.k)
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: SetPartitionsTk(3.5).list() #random
-            [{{1, -3}, {2, 3}, {4, -4}, {-1, -2}},
-             {{2, -2}, {3, -3}, {1, -1}, {4, -4}},
-             {{1, 2}, {3, -3}, {4, -4}, {-1, -2}},
-             {{-3, -2}, {2, 3}, {1, -1}, {4, -4}},
-             {{1, 2}, {-3, -2}, {4, -4}, {3, -1}}]
-        """
-        for sp in SetPartitionsBkhalf_k.iterator(self):
-            if is_planar(sp):
-                yield sp
-
-
-
-
-#########################################################
-#Algebras
-
-class PartitionAlgebra_generic(CombinatorialAlgebra):
-    def __init__(self, R, cclass, n, k, name=None, prefix=None):
-        self.k = k
-        self.n = n
-
-        self._combinatorial_class = cclass
-
-        if name is None:
-            self._name = "Generic partition algebra with k = %s and n = %s and basis %s"%( self.k, self.n, cclass)
-        else:
-            self._name = name
-        
-        self._one = identity(ceil(self.k))
-        
-        if prefix is None:
-            self._prefix = ""
-        else:
-            self._prefix = prefix
-            
-        CombinatorialAlgebra.__init__(self, R)
-        
-    def _multiply_basis(self, left, right):
-        (sp, l) = set_partition_composition(left, right)
-        return {sp: self.n**l}
-
-
-class PartitionAlgebra_ak(PartitionAlgebra_generic):
-    def __init__(self, R, k, n, name=None):
-        if name is None:
-            name = "Partition algebra A_%s(%s)"%(k, n)
-        cclass = SetPartitionsAk(k)
-        PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix="A")
-        
-class PartitionAlgebra_bk(PartitionAlgebra_generic):
-    def __init__(self, R, k, n, name=None):
-        if name is None:
-            name = "Partition algebra B_%s(%s)"%(k, n)
-        cclass = SetPartitionsBk(k)
-        PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix="B")
-
-class PartitionAlgebra_sk(PartitionAlgebra_generic):
-    def __init__(self, R, k, n, name=None):
-        if name is None:
-            name = "Partition algebra S_%s(%s)"%(k, n)
-        cclass = SetPartitionsSk(k)
-        PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix="S")
-
-class PartitionAlgebra_pk(PartitionAlgebra_generic):
-    def __init__(self, R, k, n, name=None):
-        if name is None:
-            name = "Partition algebra P_%s(%s)"%(k, n)
-        cclass = SetPartitionsPk(k)
-        PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix="P")
-        
-class PartitionAlgebra_tk(PartitionAlgebra_generic):
-    def __init__(self, R, k, n, name=None):
-        if name is None:
-            name = "Partition algebra T_%s(%s)"%(k, n)
-        cclass = SetPartitionsTk(k)
-        PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix="T")
-   
-##########################################################
-                
-def is_planar(sp):
-    """
-    Returns True if the diagram corresponding to the set partition is planar;
-    otherwise, it returns False.
-
-    EXAMPLES:
-        sage: import sage.combinat.partition_algebra as pa
-        sage: pa.is_planar( pa.to_set_partition([[1,-2],[2,-1]]))
-        False
-        sage: pa.is_planar( pa.to_set_partition([[1,-1],[2,-2]]))
-        True
-    """
-    to_consider = map(list, sp)
-
-    #Singletons don't affect planarity
-    to_consider = filter(lambda x: len(x) > 1, to_consider)
-    n = len(to_consider)
-    
-    for i in range(n):
-        #Get the positive and negative entries of this
-        #part
-        ap = filter(lambda x: x>0, to_consider[i])
-        an = filter(lambda x: x<0, to_consider[i])
-        an = map(abs, an)
-        #print a, ap, an
-
-
-        #Check if a includes numbers in both the top and bottom rows
-        if len(ap) > 0 and len(an) > 0:
-
-            for j in range(n):
-                if i == j:
-                    continue
-                #Get the postitive and negative entries of this part
-                bp = filter(lambda x: x>0, to_consider[j])
-                bn = filter(lambda x: x<0, to_consider[j])
-                bn = map(abs, bn)
-
-                #Skip the ones that don't involve numbers in both
-                #the bottom and top rows
-                if len(bn) == 0 or len(bp) == 0:
-                    continue
-
-                #Make sure that if min(bp) > max(ap)
-                #then min(bn) >  max(an)
-                if max(bp) > max(ap):
-                    if min(bn) < min(an):
-                        return False
-
-
-        #Go through the bottom and top rows
-        for row in [ap, an]:
-            if len(row) > 1:
-                row.sort()
-                for s in range(len(row)-1):
-                    if row[s] + 1 == row[s+1]:
-                        #No gap, continue on
-                        continue
-                    else:
-                        rng = range(row[s] + 1, row[s+1])
-                        
-                        #Go through and make sure any parts that
-                        #contain numbers in this range are completely
-                        #contained in this range
-                        for j in range(n):
-                            if i == j:
-                                continue
-
-                            #Make sure we make the numbers negative again
-                            #if we are in the bottom row
-                            if row is ap:
-                                sr = Set(rng)
-                            else:
-                                sr = Set(map(lambda x: -1*x, rng))
-
-                            
-                            sj = Set(to_consider[j])
-                            intersection = sr.intersection(sj)
-                            if intersection:
-                                if sj != intersection:
-                                    return False
-
-    return True
-
-   
-def to_graph(sp):
-    """
-    Returns a graph representing the set partition sp.
-    
-    EXAMPLES:
-        sage: import sage.combinat.partition_algebra as pa
-        sage: g = pa.to_graph( pa.to_set_partition([[1,-2],[2,-1]])); g
-        Graph on 4 vertices
-       
-        sage: g.vertices() #random
-        [1, 2, -2, -1]
-        sage: g.edges() #random
-        [(1, -2, None), (2, -1, None)]
-    """
-    g = Graph()
-    for part in sp:
-        part_list = list(part)
-        if len(part_list) > 0:
-            g.add_vertex(part_list[0])
-        for i in range(1, len(part_list)):
-            g.add_vertex(part_list[i])
-            g.add_edge(part_list[i-1], part_list[i])
-    return g
-
-def pair_to_graph(sp1, sp2):
-    """
-    Returns a graph consisting of the graphs of set partitions sp1
-    and sp2 along with edges joining the bottom row (negative numbers)
-    of sp1 to the top row (positive numbers) of sp2.
-
-    EXAMPLES:
-        sage: import sage.combinat.partition_algebra as pa
-        sage: sp1 = pa.to_set_partition([[1,-2],[2,-1]])
-        sage: sp2 = pa.to_set_partition([[1,-2],[2,-1]])        
-        sage: g = pa.pair_to_graph( sp1, sp2 ); g
-        Graph on 8 vertices
-
-
-        sage: g.vertices() #random
-        [(1, 2), (-1, 1), (-2, 2), (-1, 2), (-2, 1), (2, 1), (2, 2), (1, 1)]
-        sage: g.edges() #random
-        [((1, 2), (-1, 1), None),
-         ((1, 2), (-2, 2), None),
-         ((-1, 1), (2, 1), None),
-         ((-1, 2), (2, 2), None),
-         ((-2, 1), (1, 1), None),
-         ((-2, 1), (2, 2), None)]
-    """
-    g = Graph()
-
-    #Add the first set partition to the graph
-    for part in sp1:
-        part_list = list(part)
-        if len(part_list) > 0:
-            g.add_vertex( (part_list[0],1) )
-
-            #Add the edge to the second part of the graph
-            if part_list[0] < 0 and len(part_list) > 1:
-                g.add_edge( (part_list[0], 1), (abs(part_list[0]),2)  )
-            
-        for i in range(1, len(part_list)):
-            g.add_vertex( (part_list[i],1) )
-            
-            #Add the edge to the second part of the graph
-            if part_list[i] < 0:
-                g.add_edge( (part_list[i], 1), (abs(part_list[i]),2) )
-
-            #Add the edge between parts
-            g.add_edge( (part_list[i-1],1), (part_list[i],1) )
-
-    #Add the second set partition to the graph
-    for part in sp2:
-        part_list = list(part)
-        if len(part_list) > 0:
-            g.add_vertex( (part_list[0],2) )
-        for i in range(1, len(part_list)):
-            g.add_vertex( (part_list[i],2) )
-            g.add_edge( (part_list[i-1],2), (part_list[i],2) )
-
-            
-    return g
-
-def propagating_number(sp):
-    """
-    Returns the propagating number of the set partition sp.
-    The propagating number is the number of blocks with
-    both a positive and negative number.
-
-    EXAMPLES:
-        sage: import sage.combinat.partition_algebra as pa
-        sage: sp1 = pa.to_set_partition([[1,-2],[2,-1]])
-        sage: sp2 = pa.to_set_partition([[1,2],[-2,-1]])        
-        sage: pa.propagating_number(sp1)
-        2
-        sage: pa.propagating_number(sp2)
-        0
-    """
-    pn = 0
-    for part in sp:
-        if min(part) < 0  and max(part) > 0:
-            pn += 1
-    return pn
-
-def to_set_partition(l,k=None):
-    """
-    Coverts a list of a list of numbers to a set partitions. Each
-    list of numbers in the outer list specifies the numbers
-    contained in one of the blocks in the set partition.
-
-    If k is specified, then the set partition will be a
-    set partition of {1, ..., k, -1, ..., -k}.  Otherwise,
-    k will default to the minimum number needed to contain all
-    of the specified numbers.
-
-    EXAMPLES:
-        sage: import sage.combinat.partition_algebra as pa
-        sage: pa.to_set_partition([[1,-1],[2,-2]]) == pa.identity(2)
-        True
-    """
-    if k == None:
-        k = max( map( lambda x: max( map(abs, x) ), l) )
-
-    to_be_added = Set( range(1, k+1) + map(lambda x: -1*x, range(1, k+1) ) )
-    
-    sp = []
-    for part in l:
-        spart = Set(part)
-        to_be_added -= spart
-        sp.append(spart)
-
-    for singleton in to_be_added:
-        sp.append(Set([singleton]))
-
-    return Set(sp)
-
-def identity(k):
-    """
-    Returns the identity set partition {{1, -1}, ..., {k, -k}}
-
-    EXAMPLES:
-        sage: import sage.combinat.partition_algebra as pa
-        sage: pa.identity(2)
-        {{2, -2}, {1, -1}}
-    """
-    res = []
-    for i in range(1, k+1):
-        res.append(Set([i, -i]))
-    return Set(res)
-
-
-def set_partition_composition(sp1, sp2):
-    """
-    Returns a tuple consisting of the composition of the set
-    partitions sp1 and sp2 and the number of components removed
-    from the middle rows of the graph.
-
-    EXAMPLES:
-        sage: import sage.combinat.partition_algebra as pa
-        sage: sp1 = pa.to_set_partition([[1,-2],[2,-1]])
-        sage: sp2 = pa.to_set_partition([[1,-2],[2,-1]])
-        sage: pa.set_partition_composition(sp1, sp2) == (pa.identity(2), 0)
-        True
-    """
-    g = pair_to_graph(sp1, sp2)
-    connected_components = g.connected_components()
-
-    res = []
-    total_removed = 0
-    for cc in connected_components:
-        #Remove the vertices that live in the middle two rows
-        new_cc = filter(lambda x: not ( (x[0]<0 and x[1] == 1) or (x[0]>0 and x[1]==2)), cc)
-
-        if new_cc == []:
-            if len(cc) > 1:
-                total_removed += 1
-        else:
-            res.append( Set(map(lambda x: x[0], new_cc)) )
-
-
-    return ( Set(res), total_removed )
-        
Index: sage/combinat/partitions_c.cc
===================================================================
--- sage/combinat/partitions_c.cc	(revision 6456)
+++ sage/combinat/partitions_c.cc	(revision 5746)
@@ -85,10 +85,10 @@
 
 #if defined(__sun)
-extern "C" long double fabsl (long double);
-extern "C" long double sinl (long double);
-extern "C" long double cosl (long double);
-extern "C" long double sqrtl (long double);
-extern "C" long double coshl (long double);
-extern "C" long double sinhl (long double);
+extern long double fabsl (long double);
+extern long double sinl (long double);
+extern long double cosl (long double);
+extern long double sqrtl (long double);
+extern long double coshl (long double);
+extern long double sinhl (long double);
 #endif
 
Index: age/combinat/permutation.py
===================================================================
--- sage/combinat/permutation.py	(revision 6439)
+++ 	(revision )
@@ -1,2954 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.interfaces.all import gap, maxima
-from sage.rings.all import QQ, RR, ZZ, polygen, Integer, PolynomialRing, factorial
-from sage.rings.arith import binomial
-from sage.misc.sage_eval import sage_eval
-from sage.libs.all import pari
-from sage.matrix.all import matrix
-from sage.combinat.tools import transitive_ideal
-import sage.combinat.misc as misc
-import sage.combinat.subword as subword
-import sage.combinat.composition as composition
-from sage.combinat.composition import Composition, Compositions, Composition_class
-from sage.combinat.tableau import Tableau
-import sage.combinat.partition
-import sage.combinat.permutation_nk as permutation_nk
-import sage.rings.integer
-from sage.groups.perm_gps.permgroup_element import PermutationGroupElement
-from random import randint
-from sage.interfaces.all import gap
-from sage.graphs.graph import DiGraph
-import itertools
-import __builtin__
-from combinat import CombinatorialClass, CombinatorialObject
-import copy
-from necklace import Necklaces
-
-permutation_options = {'display':'list', 'mult':'l2r'}
-
-def PermutationOptions(**kwargs):
-    """
-    Sets the global options for elements of the permutation class.
-    The defaults are for permutations to be displayed in list notation
-    and the multiplication done from left to right (like in GAP).
-
-    display: 'list'  -- the permutations are displayed in list notation
-             'cycle' -- the permutations are displayed in cycle notation
-             'singleton' -- the permutations are displayed in cycle notation
-                            with singleton cycles shown as well.
-
-    mult: 'l2r' -- the multiplication of permutations is done like composition
-                   of functions from left to right. That is, if we think
-                   of the permutations p1 and p2 as functions, then
-                   (p1*p2)(x) = p2(p1(x)). This is the default in multiplication
-                   in GAP.
-          'r2l' -- the multiplication of permutations is done right to left
-                   so that (p1*p2)(x) = p1(p2(x))
-
-    If no parameters are set, then the function returns a copy of the
-    options dictionary.
-
-    Note that these options have no effect on PermutationGroupElements.
-
-    EXAMPLES:
-        sage: p213 = Permutation([2,1,3])
-        sage: p312 = Permutation([3,1,2])
-        sage: PermutationOptions(mult='l2r', display='list')
-        sage: po = PermutationOptions()
-        sage: po['display']
-        'list'
-        sage: p213
-        [2, 1, 3]
-        sage: PermutationOptions(display='cycle')
-        sage: p213
-        (1,2)
-        sage: PermutationOptions(display='singleton')
-        sage: p213
-        (1,2)(3)
-        sage: PermutationOptions(display='list')
-
-        sage: po['mult']
-        'l2r'
-        sage: p213*p312
-        [1, 3, 2]
-        sage: PermutationOptions(mult='r2l')
-        sage: p213*p312
-        [3, 2, 1]
-        sage: PermutationOptions(mult='l2r')
-    """
-    global permutation_options
-    if kwargs == {}:
-        return copy.copy(permutation_options)
-    
-    if 'mult' in kwargs:
-        if kwargs['mult'] not in ['l2r', 'r2l']:
-            raise ValueError, "mult must be either 'l2r' or 'r2l'"
-        else:
-            permutation_options['mult'] = kwargs['mult']
-
-    if 'display' in kwargs:
-        if kwargs['display'] not in ['list', 'cycle', 'singleton']:
-            raise ValueError, "display must be either 'cycle' or 'list'"
-        else:
-            permutation_options['display'] = kwargs['display']
-
-
-def Permutation(l):
-    """
-    EXAMPLES:
-        sage: Permutation([2,1])
-        [2, 1]
-        sage: Permutation([2, 1, 4, 5, 3])
-        [2, 1, 4, 5, 3]
-        sage: Permutation('(1,2)')
-        [2, 1]
-        sage: Permutation('(1,2)(3,4,5)')
-        [2, 1, 4, 5, 3]
-    """
-    #if l is a string, then assume it is in cycle notation
-    if isinstance(l, str):
-        cycles = l.split(")(")
-        cycles[0] = cycles[0][1:]
-        cycles[-1] = cycles[-1][:-1]
-        cycle_list = []
-        for c in cycles:
-            cycle_list.append(map(int, c.split(",")))
-        return from_cycles(sum([len(c) for c in cycle_list]), cycle_list)
-    else:
-        return Permutation_class(l)
-
-class Permutation_class(CombinatorialObject):
-    def __init__(self, l):
-        """
-        TESTS:
-            sage: p = Permutation([1,2,3])
-            sage: p == loads(dumps(p))
-            True
-        """
-        self.list = l
-        
-    def __hash__(self):
-        """
-        TESTS:
-            sage: d = {}
-            sage: p = Permutation([1,2,3])
-            sage: d[p] = 1
-            sage: d[p]
-            1
-        """
-        return str(self).__hash__()
-
-    def __str__(self):
-        """
-        TESTS:
-            sage: PermutationOptions(display='list')
-            sage: p = Permutation([2,1,3])
-            sage: str(p)
-            '[2, 1, 3]'
-            sage: PermutationOptions(display='cycle')
-            sage: str(p)
-            '(1,2)'
-            sage: PermutationOptions(display='singleton')
-            sage: str(p)
-            '(1,2)(3)'
-            sage: PermutationOptions(display='list')
-        """
-        return repr(self)
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: PermutationOptions(display='list')
-            sage: p = Permutation([2,1,3])
-            sage: repr(p)
-            '[2, 1, 3]'
-            sage: PermutationOptions(display='cycle')
-            sage: repr(p)
-            '(1,2)'
-            sage: PermutationOptions(display='singleton')
-            sage: repr(p)
-            '(1,2)(3)'
-            sage: PermutationOptions(display='list')
-        """
-        global permutation_options
-        display = permutation_options['display']
-        if display == 'list':
-            return repr(self.list)
-        elif display == 'cycle':
-            return self.cycle_string()
-        elif display == 'singleton':
-            return self.cycle_string(singletons=True)
-        else:
-            raise ValueError, "permutation_options['display'] should be one of 'list', 'cycle', or 'singleton'"
-
-    def cycle_string(self, singletons=False):
-        """
-        Returns a string of the permutation in cycle notation.
-
-        If singletons=True, it includes 1-cycles in the string.
-        
-        EXAMPLES:
-            sage: Permutation([1,2,3]).cycle_string()
-            '()'
-            sage: Permutation([2,1,3]).cycle_string()
-            '(1,2)'
-            sage: Permutation([2,3,1]).cycle_string()
-            '(1,2,3)'
-            sage: Permutation([2,1,3]).cycle_string(singletons=True)
-            '(1,2)(3)'
-        """
-        cycles = self.to_cycles(singletons=singletons)
-        if cycles == []:
-            return "()"
-        else:
-            return "".join(["("+",".join([str(l) for l in x])+")" for x in cycles])
-
-    def next(self):
-        r"""
-        Returns the permutation that follows p in lexicographic order.
-        If p is the last permutation, then next returns false.
-
-        EXAMPLES:
-            sage: p = Permutation([1, 3, 2])
-            sage: p.next()
-            [2, 1, 3]
-            sage: p = Permutation([4,3,2,1])
-            sage: p.next()
-            False
-        """
-        p = self[:]
-        n = len(self)
-        first = -1
-
-        #Starting from the end, find the first o such that
-        #p[o] < p[o+1]
-        for i in reversed(range(0,n-1)):
-            if p[i] < p[i+1]:
-                first = i
-                break
-
-        #If first is still -1, then we are already at the last permutation
-        if first == -1:
-            return False
-
-        #Starting from the end, find the first j such that p[j] > p[first]
-        j = n - 1
-        while p[j] < p[first]:
-            j -= 1
-
-        #Swap positions first and j
-        (p[j], p[first]) = (p[first], p[j])
-
-        #Reverse the list between first and the end
-        first_half = p[:first+1]
-        last_half  = p[first+1:]
-        last_half.reverse()
-        p = first_half + last_half
-
-        return Permutation(p)
-
-    def prev(self):
-        r"""
-        Returns the permutation that comes directly before p
-        in lexicographic order.  If p is the first permutation, then
-        it returns False.
-
-        EXAMPLES:
-            sage: p = Permutation([1,2,3])
-            sage: p.prev()
-            False
-            sage: p = Permutation([1,3,2])
-            sage: p.prev()
-            [1, 2, 3]
-        """
-
-        p = self[:]
-        n = len(self)
-        first = -1
-
-        #Starting from the beginning, find the first o such that
-        #p[o] > p[o+1]
-        for i in range(0, n-1):
-            if p[i] > p[i+1]:
-                first = i
-                break
-
-        #If first is still -1, that is we didn't find any descents,
-        #then we are already at the last permutation
-        if first == -1:
-            return False
-
-        #Starting from the end, find the first j such that p[j] > p[first]
-        j = n - 1
-        while p[j] > p[first]:
-            j -= 1
-
-        #Swap positions first and j
-        (p[j], p[first]) = (p[first], p[j])
-
-        #Reverse the list between first+1 and end
-        first_half = p[:first+1]
-        last_half  = p[first+1:]
-        last_half.reverse()
-        p = first_half + last_half
-
-        return Permutation(p)
-
-    
-
-    def to_cycles(self, singletons=True):
-        r"""
-        Returns the permutation p as a list of disjoint cycles.
-
-        EXAMPLES:
-            sage: Permutation([2,1,3,4]).to_cycles()
-            [(1, 2), (3,), (4,)]
-            sage: Permutation([2,1,3,4]).to_cycles(singletons=False)
-            [(1, 2)]
-        """
-        p = self[:]
-        cycles = []
-        toConsider = -1
-
-        #Create the list [1,2,...,len(p)]
-        l = [ i+1 for i in range(len(p))]
-        cycle = []
-
-        #Go through until we've considered every number between
-        #1 and len(p)
-        while len(l) > 0:
-            #If we are at the end of a cycle
-            #then we want to add it to the cycles list
-            if toConsider == -1:
-                #Add the cycle to the list of cycles
-                if singletons:
-                    if cycle != []:
-                        cycles.append(tuple(cycle))
-                else:
-                    if len(cycle) > 1:
-                        cycles.append(tuple(cycle))
-
-
-                #Start with the first element in the list
-                toConsider = l[0]
-                l.remove(toConsider)
-                cycle = [ toConsider ]
-                cycleFirst = toConsider
-
-            #Figure out where the element under consideration
-            #gets mapped to.
-            next = p[toConsider - 1]
-
-            #If the next element is the first one in the list
-            #then we've reached the end of the cycle
-            if next == cycleFirst:
-                toConsider = -1
-            else:
-                cycle.append( next )    
-                l.remove( next )
-                toConsider = next
-
-        #When we're finished, add the last cycle
-        if singletons:
-            if cycle != []:
-                cycles.append(tuple(cycle))
-        else:
-            if len(cycle) > 1:
-                cycles.append(tuple(cycle))
-
-        return cycles
-
-    def to_permutation_group_element(self):
-        """
-        Returns a PermutationGroupElement equal to self.
-
-        EXAMPLES:
-            sage: p = Permutation([2,1,4,3])
-            sage: pge = p.to_permutation_group_element()
-            sage: pge
-            (1,2)(3,4)
-        """
-
-        return PermutationGroupElement(self.to_cycles(singletons=False))
-
-    def signature(p):
-        r"""
-        Returns the signature of a permutation.
-
-        EXAMPLES:
-            sage: Permutation([4, 2, 3, 1, 5]).signature()
-            -1
-
-        """
-        return (-1)**(len(p)-len(p.to_cycles()))
-    
-
-    def is_even(self):
-        r"""
-        Returns True if the permutation p is even and false otherwise.
-
-        EXAMPLES:
-            sage: Permutation([1,2,3]).is_even()
-            True
-            sage: Permutation([2,1,3]).is_even()
-            False
-        """
-
-        if self.signature() == 1:
-            return True
-        else:
-            return False
-
-
-    def to_matrix(self):
-        r"""
-        Returns a matrix representing the permutation.
-
-        EXAMPLES:
-            sage: Permutation([1,2,3]).to_matrix()
-            [1 0 0]
-            [0 1 0]
-            [0 0 1]
-
-            sage: Permutation([1,3,2]).to_matrix()
-            [1 0 0]
-            [0 0 1]
-            [0 1 0]
-
-          Notice that matrix multiplication corresponds to permutation
-          multiplication only when the permutation option mult='r2l'
-
-            sage: PermutationOptions(mult='r2l')
-            sage: p = Permutation([2,1,3])
-            sage: q = Permutation([3,1,2])
-            sage: (p*q).to_matrix()
-            [0 0 1]
-            [0 1 0]
-            [1 0 0]
-            sage: p.to_matrix()*q.to_matrix()
-            [0 0 1]
-            [0 1 0]
-            [1 0 0]
-            sage: PermutationOptions(mult='l2r')
-            sage: (p*q).to_matrix()
-            [1 0 0]
-            [0 0 1]
-            [0 1 0]
-        """
-        p = self[:]
-        n = len(p)
-
-        #Build the dictionary of entries since the matrix
-        #is extremely sparse
-        entries = {}
-        for i in range(n):
-            entries[(p[i]-1,i)] = 1
-        return matrix(n, entries, sparse = True)
-
-    def __mul__(self, rp):
-        """
-        TESTS:
-            sage: p213 = Permutation([2,1,3])
-            sage: p312 = Permutation([3,1,2])
-            sage: PermutationOptions(mult='l2r')
-            sage: p213*p312
-            [1, 3, 2]
-            sage: PermutationOptions(mult='r2l')
-            sage: p213*p312
-            [3, 2, 1]
-            sage: PermutationOptions(mult='l2r')
-        """
-        global permutation_options
-        if permutation_options['mult'] == 'l2r':
-            return self._left_to_right_multiply_on_right(rp)
-        else:
-            return self._left_to_right_multiply_on_left(rp)
-
-    def __rmul__(self, lp):
-        """
-        TESTS:
-            sage: p213 = Permutation([2,1,3])
-            sage: p312 = Permutation([3,1,2])
-            sage: PermutationOptions(mult='l2r')
-            sage: p213*p312
-            [1, 3, 2]
-            sage: PermutationOptions(mult='r2l')
-            sage: p213*p312
-            [3, 2, 1]
-            sage: PermutationOptions(mult='l2r')
-        """
-        global permutation_options
-        if permutation_options['mult'] == 'l2r':
-            return self._left_to_right_multiply_on_left(lp)
-        else:
-            return self._left_to_right_multiply_on_right(lp)     
-
-    def _left_to_right_multiply_on_left(self,lp):
-        """
-        EXAMPLES:
-            sage: p = Permutation([2,1,3])
-            sage: q = Permutation([3,1,2])
-            sage: p._left_to_right_multiply_on_left(q)
-            [3, 2, 1]
-            sage: q._left_to_right_multiply_on_left(p)
-            [1, 3, 2]
-        """
-        #Pad the permutations if they are of
-        #different lengths
-        new_lp = lp[:] + [i+1 for i in range(len(lp), len(self))]
-        new_p1 = self[:] + [i+1 for i in range(len(self), len(lp))]
-        return Permutation([ new_p1[i-1] for i in new_lp ])     
-    
-
-    def _left_to_right_multiply_on_right(self, rp):
-        """
-        EXAMPLES:
-            sage: p = Permutation([2,1,3])
-            sage: q = Permutation([3,1,2])
-            sage: p._left_to_right_multiply_on_right(q)
-            [1, 3, 2]
-            sage: q._left_to_right_multiply_on_right(p)
-            [3, 2, 1]
-        """
-        #Pad the permutations if they are of
-        #different lengths
-        new_rp = rp[:] + [i+1 for i in range(len(rp), len(self))]
-        new_p1 = self[:] + [i+1 for i in range(len(self), len(rp))]
-        return Permutation([ new_rp[i-1] for i in new_p1 ]) 
-
-
-    ########
-    # Rank #
-    ########
-
-    def rank(self):
-        r"""
-        Returns the rank of a permutation in lexicographic
-        ordering.
-
-        EXAMPLES:
-            sage: Permutation([1,2,3]).rank()
-            0
-            sage: Permutation([1, 2, 4, 6, 3, 5]).rank()
-            10
-            sage: perms = Permutations(6).list()
-            sage: [p.rank() for p in perms ] == range(factorial(6))
-            True
-        """
-        n = len(self)
-
-        factoradic = self.to_lehmer_code()
-
-        #Compute the index
-        rank = 0
-        for i in reversed(range(0, n)):
-            rank += factoradic[n-1-i]*factorial(i)
-
-        return rank
-
-    ##############
-    # Inversions #
-    ##############
-
-    def to_inversion_vector(self):
-        r"""
-        Returns the inversion vector of a permutation p.
-
-        If iv is the inversion vector, then iv[i] is the number of elements
-        larger than i that appear to the left of i in the permutation.
-
-        EXAMPLES:
-            sage: Permutation([5,9,1,8,2,6,4,7,3]).to_inversion_vector()
-            [2, 3, 6, 4, 0, 2, 2, 1, 0]
-            sage: Permutation([8,7,2,1,9,4,6,5,10,3]).to_inversion_vector()
-            [3, 2, 7, 3, 4, 3, 1, 0, 0, 0]
-            sage: Permutation([3,2,4,1,5]).to_inversion_vector()
-            [3, 1, 0, 0, 0]
-
-        """
-        p = self[:]
-        inversion_vector = [0]*len(p)
-        for i in range(len(p)):
-            j = 0
-            while p[j] != i+1:
-                if p[j] > i+1:
-                    inversion_vector[i] += 1
-                j += 1
-
-        return inversion_vector
-
-
-    def inversions(self):
-        r"""
-        Returns a list of the inversions of permutation p.
-
-        EXAMPLES:
-            sage: Permutation([3,2,4,1,5]).inversions()
-            [[0, 1], [0, 3], [1, 3], [2, 3]]
-
-
-        """
-        p = self[:]
-        inversion_list = []
-
-        for i in range(len(p)):
-            for j in range(i+1,len(p)):
-                if  p[i] > p[j]:
-                    #inversion_list.append((p[i],p[j]))
-                    inversion_list.append([i,j])
-
-        return inversion_list
-
-
-
-    def number_of_inversions(self):
-        r"""
-        Returns the number of inversions in the permutation p.
-
-        An inversion of a permutation is a pair of elements (p[i],p[j])
-        with i > j and p[i] < p[j].
-
-        REFERENCES:
-            http://mathworld.wolfram.com/PermutationInversion.html
-
-        EXAMPLES:
-            sage: Permutation([3,2,4,1,5]).number_of_inversions()
-            4
-            sage: Permutation([1, 2, 6, 4, 7, 3, 5]).number_of_inversions()
-            6
-
-        """
-
-        return sum(self.to_inversion_vector())
-
-
-    def length(self):
-        r"""
-        Returns the length of a permutation p.  The length is given by the
-        number of inversions of p.
-
-        EXAMPLES:
-            sage: Permutation([5, 1, 3, 2, 4]).length()
-            5
-        """
-        return self.number_of_inversions()
-
-    def inverse(self):
-        r"""
-        Returns the inverse of a permutation
-
-        EXAMPLES:
-            sage: Permutation([3,8,5,10,9,4,6,1,7,2]).inverse()
-            [8, 10, 1, 6, 3, 7, 9, 2, 5, 4]
-            sage: Permutation([2, 4, 1, 5, 3]).inverse()
-            [3, 1, 5, 2, 4]
-
-
-        """
-        return Permutation([self.index(i+1)+1 for i in range(len(self))])
-
-    def runs(self):
-        r"""
-        Returns a list of the runs in the permutation p.
-
-        REFERENCES:
-            http://mathworld.wolfram.com/PermutationRun.html
-
-        EXAMPLES:
-            sage: Permutation([1,2,3,4]).runs()
-            [[1, 2, 3, 4]]
-            sage: Permutation([4,3,2,1]).runs()
-            [[4], [3], [2], [1]]
-            sage: Permutation([2,4,1,3]).runs()
-            [[2, 4], [1, 3]]
-        """
-        p = self[:]
-        runs = []
-        current_value = p[0]
-        current_run = [p[0]]
-        for i in range(1, len(p)):
-            if p[i] < current_value:
-                runs.append(current_run)
-                current_run = [p[i]]
-            else:
-                current_run.append(p[i])
-
-            current_value = p[i]
-        runs.append(current_run)
-
-        return runs
-
-    def longest_increasing_subsequence(self):
-        r"""
-        Returns a list of the longest increasing subsequences of
-        the permutation p.
-
-        EXAMPLES:
-            sage: Permutation([2,3,4,1]).longest_increasing_subsequence()
-            [[2, 3, 4]]
-        """
-        runs = self.runs()
-        lis = []
-        max_length = max([len(r) for r in runs])
-        for run in runs:
-            if len(run) == max_length:
-                lis.append(run)
-        return lis
-
-    def cycle_type(self):
-        r"""
-        Returns a partition of len(p) corresponding to the cycle
-        type of p.  This is a non-increasing sequence of the
-        cycle lengths of p.
-
-        EXAMPLES:
-            sage: Permutation([3,1,2,4]).cycle_type()
-            [3, 1]
-        """
-        cycle_type = [len(c) for c in self.to_cycles()]
-        cycle_type.sort(reverse=True)
-        return sage.combinat.partition.Partition(cycle_type)
-
-    def to_lehmer_code(self):
-        r"""
-        Returns the Lehmer code of the permutation p.
-
-        EXAMPLES:
-            sage: p = Permutation([2,1,3])
-            sage: p.to_lehmer_code()
-            [1, 0, 0]
-            sage: q = Permutation([3,1,2])
-            sage: q.to_lehmer_code()
-            [2, 0, 0]
-        """
-        p = self[:]
-        n = len(p)
-        lehmer = [None]*n
-        checked = [0]*n
-        ident = range(1,n+1)
-
-        #Compute the factoradic / Lehmer code of the permutation
-        for i in range(n):
-            j = 0
-            pos = 0
-            while j < n:
-                if checked[j] != 1:
-                    if ident[j] == p[i]:
-                        checked[j] = 1
-                        break
-                    pos += 1
-                j += 1
-            lehmer[i] = pos
-
-        return lehmer
-
-
-    def to_lehmer_cocode(self):
-        r"""
-        Returns the Lehmer cocode of p.
-
-        EXAMPLES:
-            sage: p = Permutation([2,1,3])
-            sage: p.to_lehmer_cocode()
-            [0, 1, 0]
-            sage: q = Permutation([3,1,2])
-            sage: q.to_lehmer_cocode()
-            [0, 1, 1]
-        """
-        p = self[:]
-        n = len(p)
-        cocode = [0] * n
-        for i in range(1, n):
-            for j in range(0, i):
-                if p[j] > p[i]:
-                    cocode[i] += 1
-        return cocode
-
-
-
-    #################
-    # Reduced Words #
-    #################
-
-    def reduced_word(self):
-        r"""
-        Returns the reduced word of a permutation.
-
-        EXAMPLES:
-            sage: Permutation([3,5,4,6,2,1]).reduced_word()
-            [2, 1, 4, 3, 2, 4, 3, 5, 4, 5]
-
-        """
-        code = self.to_lehmer_code()
-        reduced_word = []
-        for piece in  [ [ i + code[i] - j for j in range(code[i])] for i in range(len(code))]:
-            reduced_word += piece
-
-        return reduced_word
-
-    def reduced_words(self):
-        r"""
-        Returns a list of the reduced words of the permutation p.
-
-        EXAMPLES:
-            sage: Permutation([2,1,3]).reduced_words()
-            [[1]]
-            sage: Permutation([3,1,2]).reduced_words()
-            [[2, 1]]
-            sage: Permutation([3,2,1]).reduced_words()
-            [[1, 2, 1], [2, 1, 2]]
-            sage: Permutation([3,2,4,1]).reduced_words()
-            [[1, 2, 3, 1], [1, 2, 1, 3], [2, 1, 2, 3]]
-        """
-        p = self[:]
-        n = len(p)
-        rws = []
-        descents = self.descents()
-
-        if len(descents) == 0:
-            return [[]]
-
-        for d in descents:
-            pp = p[:d] + [p[d+1]] + [p[d]] + p[d+2:]
-            z = lambda x: x + [d+1]
-            rws += (map(z, Permutation(pp).reduced_words()))
-
-        return rws
-
-
-
-    def reduced_word_lexmin(self):
-        r"""
-        Returns a lexicographically minimal reduced word of a permutation.
-
-        EXAMPLES:
-            sage: Permutation([3,4,2,1]).reduced_word_lexmin()
-            [1, 2, 1, 3, 2]
-        """
-        cocode = self.inverse().to_lehmer_cocode()
-
-        rw = []
-        for i in range(len(cocode)):
-            piece = [j+1 for j in range(i-cocode[i],i)]
-            piece.reverse()
-            rw += piece
-
-        return rw
-
-
-    ################
-    # Fixed Points #
-    ################
-
-    def fixed_points(self):
-        r"""
-        Returns a list of the fixed points of the permutation p.
-
-        EXAMPLES:
-            sage: Permutation([1,3,2,4]).fixed_points()
-            [1, 4]
-            sage: Permutation([1,2,3,4]).fixed_points()
-            [1, 2, 3, 4]
-        """
-        fixed_points = []
-        for i in range(len(self)):
-            if i+1 == self[i]:
-                fixed_points.append(i+1)
-
-        return fixed_points
-
-    def number_of_fixed_points(self):
-        r"""
-        Returns the number of fixed points of the permutation p.
-
-        EXAMPLES:
-            sage: Permutation([1,3,2,4]).number_of_fixed_points()
-            2
-            sage: Permutation([1,2,3,4]).number_of_fixed_points()
-            4
-        """
-
-        return len(self.fixed_points())
-
-
-    ############
-    # Recoils  #
-    ############
-    def recoils(self):
-        r"""
-        Returns the list of the positions of the recoils of the permutation p.
-
-        A recoil of a permutation is an integer i such that i+1 is to the
-        left of it.
-
-
-        EXAMPLES:
-            sage: Permutation([1,4,3,2]).recoils()
-            [2, 3]
-        """
-        p = self
-        recoils  = []
-        for i in range(len(p)):
-            if p[i] != len(self) and self.index(p[i]+1) < i:
-                recoils.append(i)
-
-        return recoils
-
-    def number_of_recoils(self):
-        r"""
-        Returns the number of recoils of the permutation p.
-
-        EXAMPLES:
-            sage: Permutation([1,4,3,2]).number_of_recoils()
-            2
-
-        """
-        return len(self.recoils())
-
-    def recoils_composition(self):
-        """
-        Returns the composition corresponding to recoils of
-        the permutation.
-
-        EXAMPLES:
-            sage: Permutation([1,3,2,4]).recoils_composition()
-            [3]
-        """
-        d = self.recoils()
-        d = [ -1 ] + d
-        return [ d[i+1]-d[i] for i in range(len(d)-1)]
-
-
-    ############
-    # Descents #
-    ############
-
-    def descents(self, final_descent=False):
-        r"""
-        Returns the list of the descents of the permutation p.
-
-        A descent of a permutation is an integer i such that p[i]>p[i+1].
-        With the final_descent option, the last position of a non empty permutation
-        is also considered as a descent.
-
-        EXAMPLES:
-            sage: Permutation([1,4,3,2]).descents()
-            [1, 2]
-            sage: Permutation([1,4,3,2]).descents(final_descent=True)
-            [1, 2, 3]
-        """
-        p = self
-        descents = []
-        for i in range(len(p)-1):
-            if p[i] > p[i+1]:
-                descents.append(i)
-
-        if final_descent:
-            descents.append(len(p)-1)
-
-        return descents
-
-    def number_of_descents(self, final_descent=False):
-        r"""
-        Returns the number of descents of the permutation p.
-
-        EXAMPLES:
-            sage: Permutation([1,4,3,2]).number_of_descents()
-            2
-            sage: Permutation([1,4,3,2]).number_of_descents(final_descent=True)
-            3
-        """
-        return len(self.descents(final_descent))
-
-    def descents_composition(self):
-        """
-        Returns the composition corresponding to the descents of
-        the permutation.
-
-        EXAMPLES:
-            sage: Permutation([1,3,2,4]).descents_composition()
-            [2, 2]
-        """
-        d = self.descents()
-        d = [ -1 ] + d + [len(self)-1]
-        return [ d[i+1]-d[i] for i in range(len(d)-1)]
-
-    def descent_polynomial(self):
-        r"""
-        Returns the descent polynomial of the permutation p.
-
-        The descent polymomial of p is the product of all the
-        z[p[i]] where i ranges over the descents of p.
-
-        REFERENCES:
-            Garsia and Stanton 1984
-
-        EXAMPLES:
-            sage: Permutation([2,1,3]).descent_polynomial()
-            z1
-            sage: Permutation([4,3,2,1]).descent_polynomial()
-            z1*z2^2*z3^3
-        """
-        p = self
-        z = []
-        P = PolynomialRing(ZZ, len(p), 'z')
-        z = P.gens()
-        result = 1
-        pol = 1
-        for i in range(len(p)-1):
-            pol *= z[p[i]-1]
-            if p[i] > p[i+1]:
-                result *= pol
-
-        return result
-
-
-    ##############
-    # Major Code #
-    ##############
-
-    def major_index(self, final_descent=False):
-        r"""
-        Returns the major index of the permutation p.
-
-        The major index is the sum of the descents of p. Since our permutation
-        indices are 0-based, we need to add one the number of descents.
-
-        EXAMPLES:
-            sage: Permutation([2,1,3]).major_index()
-            1
-            sage: Permutation([3,4,1,2]).major_index()
-            2
-            sage: Permutation([4,3,2,1]).major_index()
-            6
-        """
-        descents = self.descents(final_descent)
-
-        return sum(descents)+len(descents)
-
-
-    def to_major_code(self, final_descent=False):
-        r"""
-        Returns the major code of the permutation p, which is defined
-        as the list [m1-m2, m2-m3,..,mn] where mi := maj(pi) is the
-        major indices of the permutation math obtained by erasing the
-        letters smaller than math in p.
-
-        REFERENCES:
-            Carlitz, L. 'q-Bernoulli and Eulerian Numbers' Trans. Amer. Math. Soc. 76 (1954) 332-350
-            Skandera, M. 'An Eulerian Partner for Inversions', Sem. Lothar. Combin. 46 (2001) B46d.
-
-        EXAMPLES:
-            sage: Permutation([9,3,5,7,2,1,4,6,8]).to_major_code()
-            [5, 0, 1, 0, 1, 2, 0, 1, 0]
-            sage: Permutation([2,8,4,3,6,7,9,5,1]).to_major_code()
-            [8, 3, 3, 1, 4, 0, 1, 0, 0]
-        """
-        p = self
-        major_indices = [0]*(len(p)+1)
-        smaller = p[:]
-        for i in range(len(p)):
-            major_indices[i] = Permutation(smaller).major_index(final_descent)
-            #Create the permutation that "erases" all the numbers
-            #smaller than i+1
-            smaller.remove(1)
-            smaller = [i-1 for i in smaller]
-
-        major_code = [ major_indices[i] - major_indices[i+1] for i in range(len(p)) ]
-        return major_code
-
-    #########
-    # Peaks #
-    #########
-
-    def peaks(self):
-        r"""
-        Returns a list of the peaks of the permutation p.
-
-        A peak of a permutation is an integer i such that
-        p[i-1] <= p[i] and p[i] > p[i+1].
-
-        EXAMPLES:
-            sage: Permutation([1,3,2,4,5]).peaks()
-            [1]
-            sage: Permutation([4,1,3,2,6,5]).peaks()
-            [2, 4]
-        """
-        p = self
-        peaks = []
-        for i in range(1,len(p)-1):
-            if p[i-1] <= p[i] and p[i] > p[i+1]:
-                peaks.append(i)
-
-        return peaks
-
-
-    def number_of_peaks(self):
-        r"""
-        Returns the number of peaks of the permutation p.
-
-        A peak of a permutation is an integer i such that
-        p[i-1] <= p[i] and p[i] > p[i+1].
-
-        EXAMPLES:
-            sage: Permutation([1,3,2,4,5]).number_of_peaks()
-            1
-            sage: Permutation([4,1,3,2,6,5]).number_of_peaks()
-            2
-        """
-        return len(self.peaks())
-
-    #############
-    # Saliances #
-    #############
-
-    def saliances(self):
-        r"""
-        Returns a list of the saliances of the permutation p.
-
-        A saliance of a permutation p is an integer i such that
-        p[i] > p[j] for all j > i.
-
-        EXAMPLES:
-            sage: Permutation([2,3,1,5,4]).saliances()
-            [3, 4]
-            sage: Permutation([5,4,3,2,1]).saliances()
-            [0, 1, 2, 3, 4]
-        """
-        p = self
-        saliances = []
-        for i in range(len(p)):
-            is_saliance = True
-            for j in range(i+1, len(p)):
-                if p[i] <= p[j]:
-                    is_saliance = False
-            if is_saliance:
-                saliances.append(i)
-
-        return saliances
-
-
-    def number_of_saliances(self):
-        r"""
-        Returns the number of saliances of the permutation p.
-
-        EXAMPLES:
-            sage: Permutation([2,3,1,5,4]).number_of_saliances()
-            2
-            sage: Permutation([5,4,3,2,1]).number_of_saliances()
-            5
-        """
-        return len(self.saliances())
-
-    ################
-    # Bruhat Order #
-    ################
-    def bruhat_lequal(self, p2):
-        r"""
-        Returns True if self is less than p2 in the Bruhat order.
-
-        EXAMPLES:
-            sage: Permutation([2,4,3,1]).bruhat_lequal(Permutation([3,4,2,1])) 
-            True
-
-        """
-        p1 = self
-        n1 = len(p1)
-        n2 = len(p2)
-
-        if n1 == 0:
-            return True
-
-        if p1[0] > p2[0] or p1[n1-1] < p2[n1-1]:
-            return False
-
-        for i in range(n1):
-            c = 0
-            for j in range(n1):
-                if p2[j] > i+1:
-                    c += 1
-                if p1[j] > i+1:
-                    c -= 1
-                if c < 0:
-                    return False
-
-        return True
-
-
-    def bruhat_inversions(self):
-        r"""
-        Returns the list of inversions of p such that the application of
-        this inversion to p decrements its number of inversions.
-
-        Equivalently, it returns the list of pairs (i,j), i<j  such that
-        p[i] > p[j] and such that there exists no k between i and j
-        satisfying p[i] > p[k].
-
-
-        EXAMPLES:
-            sage: Permutation([5,2,3,4,1]).bruhat_inversions()
-            [[0, 1], [0, 2], [0, 3], [1, 4], [2, 4], [3, 4]]
-            sage: Permutation([6,1,4,5,2,3]).bruhat_inversions()
-            [[0, 1], [0, 2], [0, 3], [2, 4], [2, 5], [3, 4], [3, 5]]
-        """
-        return __builtin__.list(self.bruhat_inversions_iterator())
-
-    def bruhat_inversions_iterator(self):
-        p = self
-        n = len(p)
-
-        for i in range(n-1):
-            for j in range(i+1,n):
-                if p[i] > p[j]:
-                    ok = True
-                    for k in range(i+1, j):
-                        if p[i] > p[k] and p[k] > p[j]:
-                            ok = False
-                            break
-                    if ok:
-                        yield [i,j]
-
-
-    def bruhat_succ(self):
-        r"""
-        Returns a list of the permutations strictly greater than p in the
-        Bruhat order such that there is no permutation between one of those
-        and p.
-
-        EXAMPLES:
-            sage: Permutation([6,1,4,5,2,3]).bruhat_succ()
-            [[6, 4, 1, 5, 2, 3],
-             [6, 2, 4, 5, 1, 3],
-             [6, 1, 5, 4, 2, 3],
-             [6, 1, 4, 5, 3, 2]]
-
-        """
-        return __builtin__.list(self.bruhat_succ_iterator())
-
-    def bruhat_succ_iterator(self):
-        """
-        An iterator for the permutations that are strictly greater than p in
-        the Bruhat order such that there is no permutation between one of
-        those and p.
-
-        EXAMPLES:
-            sage: [x for x in Permutation([6,1,4,5,2,3]).bruhat_succ_iterator()]
-            [[6, 4, 1, 5, 2, 3],
-             [6, 2, 4, 5, 1, 3],
-             [6, 1, 5, 4, 2, 3],
-             [6, 1, 4, 5, 3, 2]]            
-        """
-        p = self
-        n = len(p)
-
-        for z in Permutation(map(lambda x: n+1-x, p)).bruhat_inversions_iterator():
-            pp = p[:]
-            pp[z[0]] = p[z[1]]
-            pp[z[1]] = p[z[0]]
-            yield Permutation(pp)
-
-
-
-    def bruhat_pred(self):
-        r"""
-        Returns a list of the permutations strictly smaller than p in the
-        Bruhat order such that there is no permutation between one of those
-        and p.
-
-
-        EXAMPLES:
-        sage: Permutation([6,1,4,5,2,3]).bruhat_pred()
-        [[1, 6, 4, 5, 2, 3],
-         [4, 1, 6, 5, 2, 3],
-         [5, 1, 4, 6, 2, 3],
-         [6, 1, 2, 5, 4, 3],
-         [6, 1, 3, 5, 2, 4],
-         [6, 1, 4, 2, 5, 3],
-         [6, 1, 4, 3, 2, 5]]
-
-        """
-        return __builtin__.list(self.bruhat_pred_iterator())
-
-    def bruhat_pred_iterator(self):
-        """
-        An iterator for the permutations strictly smaller than p in the
-        Bruhat order such that there is no permutation between one of those
-        and p.
-
-
-        EXAMPLES:
-        sage: [x for x in Permutation([6,1,4,5,2,3]).bruhat_pred_iterator()]
-        [[1, 6, 4, 5, 2, 3],
-         [4, 1, 6, 5, 2, 3],
-         [5, 1, 4, 6, 2, 3],
-         [6, 1, 2, 5, 4, 3],
-         [6, 1, 3, 5, 2, 4],
-         [6, 1, 4, 2, 5, 3],
-         [6, 1, 4, 3, 2, 5]]
-
-        """
-        p = self
-        n = len(p)
-        for z in p.bruhat_inversions_iterator():
-            pp = p[:]
-            pp[z[0]] = p[z[1]]
-            pp[z[1]] = p[z[0]]
-            yield Permutation(pp)
-
-
-    def bruhat_smaller(self):
-        r"""
-        Returns a the combinatorial class of  permutations smaller than or equal
-        to p in the Bruhat order.
-
-        EXAMPLES:
-            sage: Permutation([4,1,2,3]).bruhat_smaller().list()
-            [[1, 2, 3, 4],
-             [1, 2, 4, 3],
-             [1, 3, 2, 4],
-             [1, 4, 2, 3],
-             [2, 1, 3, 4],
-             [2, 1, 4, 3],
-             [3, 1, 2, 4],
-             [4, 1, 2, 3]]
-
-        """
-        return StandardPermutations_bruhat_smaller(self)
-
-
-    def bruhat_greater(self):
-        r"""
-        Returns the combinatorial class of permutations greater than or equal
-        to p in the Bruhat order.
-
-        EXAMPLES:
-            sage: Permutation([4,1,2,3]).bruhat_greater().list()
-            [[4, 1, 2, 3],
-             [4, 1, 3, 2],
-             [4, 2, 1, 3],
-             [4, 2, 3, 1],
-             [4, 3, 1, 2],
-             [4, 3, 2, 1]]
-
-        """
-
-        return StandardPermutations_bruhat_greater(self)
-
-    ########################
-    # Permutohedron  Order #
-    ########################
-
-    def permutohedron_lequal(self, p2, side="right"):
-        r"""
-        Returns True if self is less than p2 in the permutohedron order.
-
-        By default, the computations are done in the right permutohedron.
-        If you pass the option side='left', then they will be done in the
-        left permutohedron.
-
-        EXAMPLES:
-            sage: p = Permutation([3,2,1,4])
-            sage: p.permutohedron_lequal(Permutation([4,2,1,3]))
-            False
-            sage: p.permutohedron_lequal(Permutation([4,2,1,3]), side='left') 
-            True
-        """
-        p1 = self
-        n1 = len(p1)
-        n2 = len(p2)
-
-        l1 = p1.number_of_inversions()
-        l2 = p2.number_of_inversions()
-
-        if l1 > l2:
-            return False
-
-        if side == "right":
-            prod = p1._left_to_right_multiply_on_right(p2.inverse())
-        else:
-            prod = p1._left_to_right_multiply_on_left(p2.inverse())
-
-        return prod.number_of_inversions() == l2 - l1
-
-    def permutohedron_succ(self, side="right"):
-        r"""
-        Returns a list of the permutations strictly greater than p in the
-        permutohedron order such that there is no permutation between
-        one of those and p.
-
-        By default, the computations are done in the right permutohedron.
-        If you pass the option side='left', then they will be done in the
-        left permutohedron.
-
-        EXAMPLES:
-            sage: p = Permutation([4,2,1,3])
-            sage: p.permutohedron_succ()
-            [[4, 2, 3, 1]]
-            sage: p.permutohedron_succ(side='left')
-            [[4, 3, 1, 2]]
-
-        """
-        p = self
-        n = len(p)
-        succ = []
-        if side == "right":
-            rise = lambda perm: filter(lambda i: perm[i] < perm[i+1], range(0,n-1))
-            for i in rise(p):
-                pp = p[:]
-                pp[i] = p[i+1]
-                pp[i+1] = p[i]
-                succ.append(Permutation(pp))
-        else:
-            advance = lambda perm: filter(lambda i: perm.index(i) < perm.index(i+1), range(1,n))
-            for i in advance(p):
-                pp = p[:]
-                pp[p.index(i)] = i+1
-                pp[p.index(i+1)] = i            
-                succ.append(Permutation(pp))
-
-        return succ
-
-
-    def permutohedron_pred(self, side="right"):
-        r"""
-        Returns a list of the permutations strictly smaller than p in the
-        permutohedron order such that there is no permutation between
-        one of those and p.
-
-        By default, the computations are done in the right permutohedron.
-        If you pass the option side='left', then they will be done in the
-        left permutohedron.
-
-        EXAMPLES:
-            sage: p = Permutation([4,2,1,3])
-            sage: p.permutohedron_pred()            
-            [[2, 4, 1, 3], [4, 1, 2, 3]]
-            sage: p.permutohedron_pred(side='left')
-            [[4, 1, 2, 3], [3, 2, 1, 4]]
-
-
-        """
-        p = self
-        n = len(p)
-        pred = []
-        if side == "right":
-            for d in p.descents():
-                pp = p[:]
-                pp[d] = p[d+1]
-                pp[d+1] = p[d]
-                pred.append(Permutation(pp))
-        else:
-            recoil = lambda perm: filter(lambda j: perm.index(j) > perm.index(j+1), range(1,n))
-            for i in recoil(p):
-                pp = p[:]
-                pp[p.index(i)] = i+1
-                pp[p.index(i+1)] = i
-                pred.append(Permutation(pp))
-        return pred
-
-
-    def permutohedron_smaller(self, side="right"):
-        r"""
-        Returns a list of permutations smaller than or equal to p in the
-        permutohedron order.
-
-        By default, the computations are done in the right permutohedron.
-        If you pass the option side='left', then they will be done in the
-        left permutohedron.
-
-        EXAMPLES:
-            sage: Permutation([4,2,1,3]).permutohedron_smaller()
-            [[1, 2, 3, 4],
-             [1, 2, 4, 3],
-             [1, 4, 2, 3],
-             [2, 1, 3, 4],
-             [2, 1, 4, 3],
-             [2, 4, 1, 3],
-             [4, 1, 2, 3],
-             [4, 2, 1, 3]]
-
-            sage: Permutation([4,2,1,3]).permutohedron_smaller(side='left')
-            [[1, 2, 3, 4],
-             [1, 3, 2, 4],
-             [2, 1, 3, 4],
-             [2, 3, 1, 4],
-             [3, 1, 2, 4],
-             [3, 2, 1, 4],
-             [4, 1, 2, 3],
-             [4, 2, 1, 3]]
-
-
-        """
-
-        return transitive_ideal(lambda x: x.permutohedron_pred(side), self)
-
-
-    def permutohedron_greater(self, side="right"):
-        r"""
-        Returns a list of permutations greater than or equal to p in the
-        permutohedron order.
-
-        By default, the computations are done in the right permutohedron.
-        If you pass the option side='left', then they will be done in the
-        left permutohedron.
-
-        EXAMPLES:
-            sage: Permutation([4,2,1,3]).permutohedron_greater()
-            [[4, 2, 1, 3], [4, 2, 3, 1], [4, 3, 2, 1]]
-            sage: Permutation([4,2,1,3]).permutohedron_greater(side='left')
-            [[4, 2, 1, 3], [4, 3, 1, 2], [4, 3, 2, 1]]
-
-
-        """
-
-        return transitive_ideal(lambda x: x.permutohedron_succ(side), self)
-
-
-    ############
-    # Patterns #
-    ############
-
-    def has_pattern(self, patt):
-        r"""
-        Returns the boolean answering the question 'Is patt a patter appearing in
-        permutation p?'
-
-        EXAMPLES:
-            sage: Permutation([3,5,1,4,6,2]).has_pattern([1,3,2])
-            True
-
-        """
-        p = self
-        n = len(p)
-        l = len(patt)
-        for pos in subword.Subwords(range(n),l):
-            if to_standard(map(lambda z: p[z] , pos)) == patt:
-                return True
-        return False
-
-
-    def pattern_positions(self, patt):
-        r"""
-        Returns the list of positions where the pattern patt appears
-        in p.
-
-        EXAMPLES:
-            sage: Permutation([3,5,1,4,6,2]).pattern_positions([1,3,2])
-            [[0, 1, 3], [2, 3, 5], [2, 4, 5]]
-
-        """
-        p = self
-
-        return __builtin__.list(itertools.ifilter(lambda pos: to_standard(map(lambda z: p[z], pos)) == patt, subword.Subwords(range(len(p)), len(patt)).iterator() ))
-
-
-    ######################
-    # Robinson-Schensted #
-    ######################
-
-    def robinson_schensted(self):
-        """
-        Returns the pair of standard tableau obtained by running the
-        Robinson-Schensted Algorithm on self.
-
-        EXAMPLES:
-            sage: p = Permutation([6,2,3,1,7,5,4])
-            sage: p.robinson_schensted()
-            [[[1, 3, 4], [2, 5], [6, 7]], [[1, 3, 5], [2, 6], [4, 7]]]
-
-        """
-
-        p = [[]]
-        q = [[]]
-
-        for i in range(1, len(self)+1):
-            #Row insert self[i-1] into p
-            row_counter = 0
-            r = p[row_counter]
-            x = self[i-1]
-            while max(r+[0]) > x:
-                y = min(filter(lambda z: z > x, r))
-                r[r.index(y)] = x
-                x = y
-                row_counter += 1
-                if row_counter == len(p):
-                    p.append([])
-                r = p[row_counter]
-            r.append(x)
-
-            
-            #Insert i into q in the same place as we inserted
-            #i into p
-            if row_counter == len(q):
-                q.append([])
-            q[row_counter].append(i)
-
-
-        return [Tableau(p),Tableau(q)]
-
-################################################################
-
-def Arrangements(mset, k):
-    r"""
-    An arrangement of mset is an ordered selection without repetitions
-    and is represented by a list that contains only elements from
-    mset, but maybe in a different order.
-
-    \code{Arrangements} returns the combinatorial class of arrangements
-    of the multiset mset that contain k elements.
-
-    EXAMPLES:
-        sage: mset = [1,1,2,3,4,4,5]
-        sage: Arrangements(mset,2).list()
-        [[1, 1],
-         [1, 2],
-         [1, 3],
-         [1, 4],
-         [1, 5],
-         [2, 1],
-         [2, 3],
-         [2, 4],
-         [2, 5],
-         [3, 1],
-         [3, 2],
-         [3, 4],
-         [3, 5],
-         [4, 1],
-         [4, 2],
-         [4, 3],
-         [4, 4],
-         [4, 5],
-         [5, 1],
-         [5, 2], 
-         [5, 3],
-         [5, 4]]
-         sage: Arrangements(mset,2).count()
-         22
-         sage: Arrangements( ["c","a","t"], 2 ).list()
-         [['c', 'a'], ['c', 't'], ['a', 'c'], ['a', 't'], ['t', 'c'], ['t', 'a']]
-         sage: Arrangements( ["c","a","t"], 3 ).list()
-         [['c', 'a', 't'],
-          ['c', 't', 'a'],
-          ['a', 'c', 't'],
-          ['a', 't', 'c'],
-          ['t', 'c', 'a'],
-          ['t', 'a', 'c']]
-    """
-    return Arrangements_msetk(mset, k)
-
-def Permutations(n=None,k=None, **kwargs):
-
-    valid_args = ['descents', 'bruhat_smaller', 'bruhat_greater',
-                  'recoils_finer', 'recoils_fatter', 'recoils']
-
-    number_of_arguments = 0
-    if n != None:
-            number_of_arguments += 1
-    else:
-        if k != None:
-            number_of_arguments += 1
-            
-
-    #Make sure that exactly one keyword was passed
-    for key in kwargs:
-        if key not in valid_args:
-            raise ValueError, "unknown keyword argument: "%key
-        number_of_arguments += 1
-
-    if number_of_arguments == 0:
-        return StandardPermutations_all()
-    
-    if number_of_arguments != 1:
-        raise ValueError, "you must specify exactly one argument"     
-
-    if n != None:
-        if isinstance(n, (int, Integer)):
-            if k == None:
-                return StandardPermutations_n(n)
-            else:
-                return Permutations_nk(n,k)
-        else:
-            if k == None:
-                return Permutations_mset(n)
-            else:
-                return Permutations_msetk(n,k)
-    elif 'descents' in kwargs:
-        if isinstance(kwargs['descents'], tuple):
-            return StandardPermutations_descents(*kwargs['descents'])
-        else:
-            return StandardPermutations_descents(kwargs['descents'], max(kwargs['descents'])+1)
-    elif 'bruhat_smaller' in kwargs:
-        return StandardPermutations_bruhat_smaller(Permutation(kwargs['bruhat_smaller']))
-    elif 'bruhat_greater' in kwargs:
-        return StandardPermutations_bruhat_greater(Permutation(kwargs['bruhat_greater']))
-    elif 'recoils_finer' in kwargs:
-        return StandardPermutations_recoilsfiner(kwargs['recoils_finer'])
-    elif 'recoils_fatter' in kwargs:
-        return StandardPermutations_recoilsfatter(kwargs['recoils_fatter'])
-    elif 'recoils' in kwargs:
-        return StandardPermutations_recoils(kwargs['recoils'])
-
-class Permutations_nk(CombinatorialClass):
-    def __init__(self, n, k):
-        """
-        TESTS:
-            sage: P = Permutations([3,2])
-            sage: P == loads(dumps(P))
-            True
-        """
-        self.n = n
-        self.k = k
-        
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Permutations(3,2))
-            'Permutations of {1,...,3} of length 2'
-        """
-        return "Permutations of {1,...,%s} of length %s"%(self.n, self.k)
-        
-    def iterator(self):
-        """
-        EXAMPLES:
-            sage: [p for p in Permutations(3,2)]
-            [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
-            sage: [p for p in Permutations(3,0)]
-            [[]]
-            sage: [p for p in Permutations(3,4)]
-            []
-        """
-        def label(x):
-            return x+1
-        for x in permutation_nk.iterator(self.n, self.k):
-            yield map(label, x)
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: Permutations(3,0).count()
-            1
-            sage: Permutations(3,1).count()
-            3
-            sage: Permutations(3,2).count()
-            6
-            sage: Permutations(3,3).count()
-            6
-            sage: Permutations(3,4).count()
-            0
-        """
-        if self.k <= self.n and self.k >= 0:
-            return factorial(self.n)/factorial(self.n-self.k)
-        else:
-            return 0
-
-class Permutations_mset(CombinatorialClass):
-    def __init__(self, mset):
-        """
-        TESTS:
-            sage: S = Permutations(['c','a','t'])
-            sage: S == loads(dumps(S))
-            True
-        """
-        self.mset = mset
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Permutations(['c','a','t']))
-            "Permutations of the (multi-)set ['c', 'a', 't']"
-        """
-        return "Permutations of the (multi-)set %s"%self.mset
-    
-    def iterator(self):
-        """
-        Algorithm based on:
-        http://marknelson.us/2002/03/01/next-permutation/
-
-        EXAMPLES:
-            sage: [ p for p in Permutations(['c','a','t'])]
-            [['c', 'a', 't'],
-             ['c', 't', 'a'],
-             ['a', 'c', 't'],
-             ['a', 't', 'c'],
-             ['t', 'c', 'a'],
-             ['t', 'a', 'c']]
-            sage: [ p for p in Permutations(['c','t','t'])]
-            [['c', 't', 't'], ['t', 'c', 't'], ['t', 't', 'c']]
-        """
-        mset = self.mset
-        n = len(self.mset)
-        lmset = __builtin__.list(mset)
-        mset_list = map(lambda x: lmset.index(x), lmset)
-        mset_list.sort()
-        
-        def label(x):
-            return lmset[x]
-
-        yield map(label, mset_list)
-
-        if n == 1:
-            return
-
-        while True:
-            one = n - 2
-            two = n - 1
-            j   = n - 1
-
-            #starting from the end, find the first o such that
-            #mset_list[o] < mset_list[o+1]
-            while two > 0 and mset_list[one] >= mset_list[two]:
-                one -= 1
-                two -= 1    
-
-            if two == 0:
-                return
-
-            #starting from the end, find the first j such that
-            #mset_list[j] > mset_list[one]
-            while mset_list[j] <= mset_list[one]:
-                j -= 1
-
-            #Swap positions one and j
-            t = mset_list[one]
-            mset_list[one] = mset_list[j]
-            mset_list[j] = t
-
-
-            #Reverse the list between two and last
-            i = int((n - two)/2)-1
-            #mset_list = mset_list[:two] + [x for x in reversed(mset_list[two:])]
-            while i >= 0:
-                t = mset_list[ i + two ]
-                mset_list[ i + two ] = mset_list[n-1 - i]
-                mset_list[n-1 - i] = t
-                i -= 1
-
-            #Yield the permutation
-            yield map(label, mset_list)
-
-        def count(self):
-            """
-            EXAMPLES:
-                sage: Permutations([1,2,3]).count()
-                6
-                sage: Permutations([1,2,2]).count()
-                3
-            """
-            lmset = __builtin__.list(mset)
-            mset_list = map(lambda x: lmset.index(x), lmset)
-            d = {}
-            for i in mset_list:
-                d[i] = d.get(i, 0) + 1
-
-            c = factorial(len(lmset))
-            for i in d:
-                if i != 1:
-                    c /= factorial(i)
-
-            return c
-                
-
-class Permutations_msetk(CombinatorialClass):
-    def __init__(self, mset, k):
-        """
-        TESTS:
-            sage: P = Permutations([1,2,2],2)
-            sage: P == loads(dumps(P))
-            True
-        """
-        self.mset = mset
-        self.k = k
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Permutations([1,2,2],2))
-            'Permutations of the (multi-)set [1, 2, 2] of length 2'
-        """
-        return "Permutations of the (multi-)set %s of length %s"%(self.mset,self.k)
-
-    def list(self):
-        """
-        EXAMPLES:
-            sage: Permutations([1,2,3],2).list()
-            [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
-            sage: Permutations([1,2,2],2).list()
-            [[1, 2], [2, 1], [2, 2]]
-         """
-        mset = self.mset
-        n = len(self.mset)
-        lmset = __builtin__.list(mset)
-        mset_list = map(lambda x: lmset.index(x), lmset)
-
-        def label(x):
-            return lmset[x]
-
-        indices = eval(gap.eval('Arrangements(%s,%s)'%(mset_list, self.k)))
-        return map(lambda ktuple: map(label, ktuple), indices)
-
-
-class Arrangements_msetk(Permutations_msetk):
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Arrangements([1,2,3],2))
-            'Arrangements of the (multi-)set [1, 2, 3] of length 2'
-        """
-        return "Arrangements of the (multi-)set %s of length %s"%(self.mset,self.k)
-
-
-class StandardPermutations_all(CombinatorialClass):
-    def __init__(self):
-        """
-        TESTS:
-            sage: SP = Permutations()
-            sage: SP == loads(dumps(SP))
-            True
-        """
-        self.object_class = Permutation_class
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Permutations())
-            'Standard permutations'
-        """
-        return "Standard permutations"
-
-    def __contains__(self,x):
-        """
-        TESTS:
-            sage: [] in Permutations()
-            False
-            sage: [1] in Permutations()
-            True
-            sage: [2] in Permutations()
-            False
-            sage: [1,2] in Permutations()
-            True
-            sage: [2,1] in Permutations()
-            True
-            sage: [1,2,2] in Permutations()
-            False
-            sage: [3,1,5,2] in Permutations()
-            False
-            sage: [3,4,1,5,2] in Permutations()
-            True
-        """
-        if isinstance(x, Permutation_class):
-            return True
-        elif isinstance(x, __builtin__.list):
-            if len(x) == 0:
-                return False
-            copy = x[:]
-            copy.sort()
-            if copy != range(1, len(x)+1):
-                return False
-            return True
-        else:
-            return False
-
-    def list(self):
-        """
-        EXAMPLES:
-            sage: Permutations().list()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError
-        """
-        raise NotImplementedError
-    
-
-class StandardPermutations_n(CombinatorialClass):
-    def __init__(self, n):
-        """
-        TESTS:
-            sage: SP = Permutations(3)
-            sage: SP == loads(dumps(SP))
-            True
-        """
-        self.n = n
-        self.object_class = Permutation_class
-
-
-    def __contains__(self,x):
-        """
-        TESTS:
-            sage: [1,2] in Permutations(2)
-            True
-            sage: [1,2] in Permutations(3)
-            False
-            sage: [3,2,1] in Permutations(3)
-            True
-        """
-        
-        return x in Permutations() and len(x) == self.n
-    
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Permutations(3))
-            'Standard permutations of 3'
-        """
-        return "Standard permutations of %s"%self.n
-    
-    def iterator(self):
-        """
-        EXAMPLES:
-            sage: [p for p in Permutations(3)]
-            [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
-        """
-        for p in Permutations_mset(range(1,self.n+1)):
-            yield Permutation_class(p)
- 
-    def count(self):
-        """
-        EXAMPLES:
-            sage: Permutations(3).count()
-            6
-            sage: Permutations(4).count()
-            24
-        """
-        return factorial(self.n)
-
-    
-    def identity(self):
-        r"""
-        Returns the identity permutation of length n.
-
-        EXAMPLES:
-            sage: Permutations(4).identity()
-            [1, 2, 3, 4]
-        """
-
-        return Permutation_class(range(1,self.n+1))
-
-    def unrank(self, r):
-        """
-        EXAMPLES:
-            sage: SP3 = Permutations(3)
-            sage: l = map(SP3.unrank, range(6))
-            sage: l == SP3.list()
-            True
-        """
-        return from_rank(self.n, r)
-
-    def rank(self, p):
-        """
-        EXAMPLES:
-            sage: SP3 = Permutations(3)
-            sage: map(SP3.rank, SP3)
-            [0, 1, 2, 3, 4, 5]
-        """
-        return Permutation(p).rank()
-
-    def random(self):
-        """
-        EXAMPLES:
-            sage: Permutations(4).random() #random
-            [3, 4, 1, 2]
-        """
-        r = randint(0, int(factorial(self.n)-1))
-        return self.unrank(r)
-
-
-
-#############################
-# Constructing Permutations #
-#############################
-def from_permutation_group_element(pge):
-    """
-    Returns a Permutation give a PermutationGroupElement pge.
-
-    EXAMPLES:
-        sage: pge = PermutationGroupElement([(1,2),(3,4)])
-        sage: permutation.from_permutation_group_element(pge)
-        [2, 1, 4, 3]
-    """
-
-    if not isinstance(pge, PermutationGroupElement):
-        raise TypeError, "pge (= %s) must be a PermutationGroupElement"%pge
-
-    return Permutation(pge.list())
-
-    
-
-def from_rank(n, rank):
-    r"""
-    Returns the permutation with the specified lexicographic
-    rank.  The permutation is of the set [1,...,n].
-
-    The permutation is computed without iteratiing through all
-    of the permutations with lower rank.  This makes it efficient
-    for large permutations.
-
-    EXAMPLES:
-        sage: Permutation([3, 6, 5, 4, 2, 1]).rank()
-        359
-        sage: [permutation.from_rank(3, i) for i in range(6)]
-        [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
-        sage: Permutations(6)[10]
-        [1, 2, 4, 6, 3, 5]
-        sage: permutation.from_rank(6,10)
-        [1, 2, 4, 6, 3, 5]
-
-    """
-
-    #Find the factoradic of rank
-    factoradic = [None] * n
-    for j in range(1,n+1):
-        factoradic[n-j] = Integer(rank % j)
-        rank = int(rank) / int(j)
-
-    return from_lehmer_code(factoradic)
-
-def from_inversion_vector(iv):
-    r"""
-    Returns the permutation corresponding to inversion vector iv.
-
-    EXAMPLES:
-        sage: permutation.from_inversion_vector([3,1,0,0,0])
-        [3, 2, 4, 1, 5]
-        sage: permutation.from_inversion_vector([2,3,6,4,0,2,2,1,0])
-        [5, 9, 1, 8, 2, 6, 4, 7, 3]
-
-    """
-
-    p = [None] * len(iv)
-    open_spots = range(len(iv))
-    
-    for i in range(len(iv)):
-        if iv[i] != 0:
-            p[open_spots[iv[i]]] = i+1
-            open_spots.remove(open_spots[iv[i]])
-        else:
-            p[open_spots[0]] = i+1
-            open_spots.remove(open_spots[0])
-    return Permutation(p)
-
-
-
-
-def from_cycles(n, cycles):
-    r"""
-    Returns the permutation corresponding to cycles.
-
-    EXAMPLES:
-        sage: permutation.from_cycles(4, [[1,2]])
-        [2, 1, 3, 4]
-        
-    """
-    
-    p = range(1,n+1)
-    for cycle in cycles:
-        first = cycle[0]
-        for i in range(len(cycle)-1):
-            p[cycle[i]-1] = cycle[i+1]
-        p[cycle[-1]-1] = first
-    return Permutation(p)
-
-def from_lehmer_code(lehmer):
-    r"""
-    Returns the permutation with Lehmer code lehmer.
-
-    EXAMPLES: 
-        sage: Permutation([2,1,5,4,3]).to_lehmer_code()
-        [1, 0, 2, 1, 0]
-        sage: permutation.from_lehmer_code(_)  
-        [2, 1, 5, 4, 3]
-
-    """
-    
-    n = len(lehmer)
-    perm = [None] * n
-    
-    #Convert the factoradic to a permutation
-    temp = [None] * n
-    for i in range(n):
-        lehmer[i] += 1
-        temp[i] = lehmer[i]
-
-    perm[n-1] = 1
-    for i in reversed(range(n-1)):
-        perm[i] = temp[i]
-        for j in range(i+1, n):
-            if perm[j] >= perm[i]:
-                perm[j] += 1
-
-    return Permutation([ p for p in perm ])
-
-def from_reduced_word(rw):
-    r"""
-    Returns the permutation corresponding to the reduced
-    word rw.
-
-    EXAMPLES:
-        sage: permutation.from_reduced_word([3,2,3,1,2,3,1])
-        [3, 4, 2, 1]
-    """
-
-    p = [i+1 for i in range(max(rw)+1)]
-
-    for i in rw:
-        (p[i-1], p[i]) = (p[i], p[i-1])
-
-    return Permutation(p)
-
-
-class StandardPermutations_descents(CombinatorialClass):
-    def __init__(self, d, n):
-        """
-        TESTS:
-            sage: P = Permutations(descents=([1,0,4,8],12))
-            sage: P == loads(dumps(P))
-            True
-        """
-        self.d = d
-        self.n = n
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Permutations(descents=([1,0,4,8],12)))
-            'Standard permutations of 12 with descents [1, 0, 4, 8]'
-        """
-        return "Standard permutations of %s with descents %s"%(self.n, self.d)
-
-    __object_class = Permutation_class
-
-    def first(self):
-        """
-        Returns the first permutation with descents d.
-
-        EXAMPLES:
-            sage: Permutations(descents=([1,0,4,8],12)).first()
-            [3, 2, 1, 4, 6, 5, 7, 8, 10, 9, 11, 12]
-
-        """
-        return descents_composition_first(Composition(descents=(self.d,self.n)))       
-
-
-    def last(self):
-        """
-        Returns the last permutation with descents d.
-
-        EXAMPLES:
-            sage: Permutations(descents=([1,0,4,8],12)).last()
-            [12, 11, 8, 9, 10, 4, 5, 6, 7, 1, 2, 3]
-        """
-        return descents_composition_last(Composition(descents=(self.d,self.n)))
-
-    def list(self):
-        """
-        Returns a list of all the permutations that have the
-        descents d.
-
-        EXAMPLES:
-             sage: Permutations(descents=([2,4,0],5)).list()
-             [[2, 1, 4, 3, 5],
-              [2, 1, 5, 3, 4],
-              [3, 1, 4, 2, 5],
-              [3, 1, 5, 2, 4],
-              [4, 1, 3, 2, 5],
-              [5, 1, 3, 2, 4],
-              [4, 1, 5, 2, 3],
-              [5, 1, 4, 2, 3],
-              [3, 2, 4, 1, 5],
-              [3, 2, 5, 1, 4],
-              [4, 2, 3, 1, 5],
-              [5, 2, 3, 1, 4],
-              [4, 2, 5, 1, 3],
-              [5, 2, 4, 1, 3],
-              [4, 3, 5, 1, 2],
-              [5, 3, 4, 1, 2]]
-         """
-
-        return descents_composition_list(Composition(descents=(self.d,self.n)))
-
-
-
-def descents_composition_list(dc):
-    """
-    Returns a list of all the permutations that have a descent
-    compositions dc.
-
-    EXAMPLES:
-        sage: permutation.descents_composition_list([1,2,2])
-        [[2, 1, 4, 3, 5],
-         [2, 1, 5, 3, 4],
-         [3, 1, 4, 2, 5],
-         [3, 1, 5, 2, 4],
-         [4, 1, 3, 2, 5],
-         [5, 1, 3, 2, 4],
-         [4, 1, 5, 2, 3],
-         [5, 1, 4, 2, 3],
-         [3, 2, 4, 1, 5],
-         [3, 2, 5, 1, 4],
-         [4, 2, 3, 1, 5],
-         [5, 2, 3, 1, 4],
-         [4, 2, 5, 1, 3],
-         [5, 2, 4, 1, 3],
-         [4, 3, 5, 1, 2],
-         [5, 3, 4, 1, 2]]
-    """
-    return map(lambda p: p.inverse(), StandardPermutations_recoils(dc).list())
-
-def descents_composition_first(dc):
-    r"""
-    Computes the smallest element of a descent class having
-    a descent decomposition dc.
-
-    EXAMPLES:
-        sage: permutation.descents_composition_first([1,1,3,4,3])
-        [3, 2, 1, 4, 6, 5, 7, 8, 10, 9, 11, 12]
-    """
-
-    if not isinstance(dc, Composition_class):
-        try:
-            dc = Composition(dc)
-        except TypeError:
-            raise TypeError, "The argument must be of type Composition"
-
-    cpl = [x for x in reversed(dc.conjugate())]
-    res = []
-    s = 0
-    for i in range(len(cpl)):
-        res += [s + cpl[i]-j for j in range(cpl[i])]
-        s   += cpl[i]
-
-    return Permutation(res)
-
-def descents_composition_last(dc):
-    r"""
-    Returns the largest element of a descent class having
-    a descent decomposition dc.
-
-    EXAMPLES:
-        sage: permutation.descents_composition_last([1,1,3,4,3])
-        [12, 11, 8, 9, 10, 4, 5, 6, 7, 1, 2, 3]
-
-    """
-    if not isinstance(dc, Composition_class):
-        try:
-            dc = Composition(dc)
-        except TypeError:
-            raise TypeError, "The argument must be of type Composition"
-    s = 0
-    res = []
-    for i in reversed(range(len(dc))):
-        res = [j for j in range(s+1,s+dc[i]+1)] + res
-        s += dc[i]
-
-    return Permutation(res)
-
-
-class StandardPermutations_recoilsfiner(CombinatorialClass):
-    def __init__(self, recoils):
-        """
-        TESTS:
-            sage: P = Permutations(recoils_finer=[2,2])
-            sage: P == loads(dumps(P))
-            True
-        """
-        self.recoils = recoils
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Permutations(recoils_finer=[2,2]))
-            'Standard permutations whose recoils composition is finer than [2, 2]'
-        """
-        return "Standard permutations whose recoils composition is finer than %s"%self.recoils
-
-    __object_class = Permutation_class
-    
-    def list(self):
-        """
-        Returns a list of all of the permutations whose
-        recoils composition is finer than recoils.
-
-        EXAMPLES:
-            sage: Permutations(recoils_finer=[2,2]).list()
-            [[1, 2, 3, 4],
-             [1, 3, 2, 4],
-             [1, 3, 4, 2],
-             [3, 1, 2, 4],
-             [3, 1, 4, 2],
-             [3, 4, 1, 2]]
-        """
-        recoils = self.recoils
-        dag = DiGraph()
-
-        #Add the nodes
-        for i in range(1, sum(recoils)+1):
-            dag.add_vertex(i)
-
-        #Add the edges to guarantee a finer recoil composition
-        pos = 1
-        for part in recoils:
-            for i in range(part-1):
-                dag.add_arc(pos, pos+1)
-                pos += 1
-            pos += 1
-
-        rcf = []
-        for le in dag.topological_sort_generator():
-            rcf.append(Permutation(le))
-        return rcf
-
-    
-class StandardPermutations_recoilsfatter(CombinatorialClass):
-    def __init__(self, recoils):
-        """
-        TESTS:
-            sage: P = Permutations(recoils_fatter=[2,2])
-            sage: P == loads(dumps(P))
-            True
-        """
-        self.recoils = recoils
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Permutations(recoils_fatter=[2,2]))
-            'Standard permutations whose recoils composition is fatter than [2, 2]'
-        """
-        return "Standard permutations whose recoils composition is fatter than %s"%self.recoils
-
-    __object_class = Permutation_class
-
-    def list(self):
-        """
-        Returns a list of all of the permutations whose
-        recoils composition is fatter than recoils.
-
-        EXAMPLES:
-            sage: Permutations(recoils_fatter=[2,2]).list()
-            [[1, 3, 2, 4],
-             [1, 3, 4, 2],
-             [1, 4, 3, 2],
-             [3, 1, 2, 4],
-             [3, 1, 4, 2],
-             [3, 2, 1, 4],
-             [3, 2, 4, 1],
-             [3, 4, 1, 2],
-             [3, 4, 2, 1],
-             [4, 1, 3, 2],
-             [4, 3, 1, 2],
-             [4, 3, 2, 1]]
-        """
-        recoils = self.recoils
-        dag = DiGraph()
-
-        #Add the nodes
-        for i in range(1, sum(recoils)+1):
-            dag.add_vertex(i)
-
-        #Add the edges to guarantee a fatter recoil composition
-        pos = 0
-        for i in range(len(recoils)-1):
-            pos += recoils[i]
-            dag.add_arc(pos+1, pos)
-
-
-        rcf = []
-        for le in dag.topological_sort_generator():
-            rcf.append(Permutation(le))
-        return rcf
-
-class StandardPermutations_recoils(CombinatorialClass):
-    def __init__(self, recoils):
-        """
-        TESTS:
-            sage: P = Permutations(recoils=[2,2])
-            sage: P == loads(dumps(P))
-            True
-        """
-        self.recoils = recoils
-        
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Permutations(recoils=[2,2]))
-            'Standard permutations whose recoils composition is [2, 2]'
-        """
-        return "Standard permutations whose recoils composition is %s"%self.recoils
-
-    __object_class = Permutation_class
-
-
-    def list(self):
-        """
-        Returns a list of all of the permutations whose
-        recoils composition is equal to recoils.
-
-        EXAMPLES:
-            sage: Permutations(recoils=[2,2]).list()
-            [[1, 3, 2, 4], [1, 3, 4, 2], [3, 1, 2, 4], [3, 1, 4, 2], [3, 4, 1, 2]]
-        """
-        
-        recoils = self.recoils
-        dag = DiGraph()
-
-        #Add all the nodes
-        for i in range(1, sum(recoils)+1):
-            dag.add_vertex(i)
-
-        #Add the edges which guarantee a finer recoil comp.
-        pos = 1
-        for part in recoils:
-            for i in range(part-1):
-                dag.add_arc(pos, pos+1)
-                pos += 1
-            pos += 1
-
-        #Add the edges which guarantee a fatter recoil comp.
-        pos = 0
-        for i in range(len(recoils)-1):
-            pos += recoils[i]
-            dag.add_arc(pos+1, pos)
-
-        rcf = []
-        for le in dag.topological_sort_generator():
-            rcf.append(Permutation(le))
-        return rcf
-
-
-
-def from_major_code(mc, final_descent=False):
-    r"""
-    Returns the permutation corresponding to major code mc.
-
-    REFERENCES:
-        Skandera, M. 'An Eulerian Partner for Inversions', Sem. Lothar. Combin. 46 (2001) B46d.
-
-    EXAMPLES:
-        sage: permutation.from_major_code([5, 0, 1, 0, 1, 2, 0, 1, 0])
-        [9, 3, 5, 7, 2, 1, 4, 6, 8]
-        sage: permutation.from_major_code([8, 3, 3, 1, 4, 0, 1, 0, 0])
-        [2, 8, 4, 3, 6, 7, 9, 5, 1]
-        sage: Permutation([2,1,6,4,7,3,5]).to_major_code()
-        [3, 2, 0, 2, 2, 0, 0]
-        sage: permutation.from_major_code([3, 2, 0, 2, 2, 0, 0])
-        [2, 1, 6, 4, 7, 3, 5]
-
-    """
-    #define w^(n) to be the one-letter word n
-    w = [len(mc)]
-
-    #for i=n-1,..,1 let w^i be the unique word obtained by inserting
-    #the letter i into the word w^(i+1) in such a way that 
-    #maj(w^i)-maj(w^(i+1)) = mc[i]
-    for i in reversed(range(1,len(mc))):
-        #Lemma 2.2 in Skandera
-
-        #Get the descents of w and place them in reverse order
-        d = Permutation(w).descents()
-        d.reverse()
-
-        #a is the list of all positions which are not descents
-        a = filter(lambda x: x not in d, range(len(w)))
-
-        #k is the number of desecents
-        k = len(d)
-
-        #d_k = -1    -- 0 in the lemma, but -1 due to 0-based indexing
-        d.append(-1)
-
-        
-        l = mc[i-1]
-
-
-        indices = d + a
-        w.insert(indices[l]+1, i)
-
-    #pi = 
-    return Permutation(w)
-
-
-class StandardPermutations_bruhat_smaller(CombinatorialClass):
-    def __init__(self, p):
-        """
-        TESTS:
-            sage: P = Permutations(bruhat_smaller=[3,2,1])
-            sage: P == loads(dumps(P))
-            True
-        """
-        self.p = p
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Permutations(bruhat_smaller=[3,2,1]))
-            'Standard permutations that are less than or equal to [3, 2, 1] in the Bruhat order'
-        """
-        return "Standard permutations that are less than or equal to %s in the Bruhat order"%self.p
-
-    def list(self):
-        r"""
-        Returns a list of permutations smaller than or equal to p in the
-        Bruhat order.
-
-        EXAMPLES:
-            sage: Permutations(bruhat_smaller=[4,1,2,3]).list()
-            [[1, 2, 3, 4],
-             [1, 2, 4, 3],
-             [1, 3, 2, 4],
-             [1, 4, 2, 3],
-             [2, 1, 3, 4],
-             [2, 1, 4, 3],
-             [3, 1, 2, 4],
-             [4, 1, 2, 3]]
-        """
-        return transitive_ideal(lambda x: x.bruhat_pred(), self.p)
-
-
-
-class StandardPermutations_bruhat_greater(CombinatorialClass):
-    def __init__(self, p):
-        """
-        TESTS:
-            sage: P = Permutations(bruhat_greater=[3,2,1])
-            sage: P == loads(dumps(P))
-            True
-        """
-        self.p = p
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Permutations(bruhat_greater=[3,2,1]))
-            'Standard permutations that are greater than or equal to [3, 2, 1] in the Bruhat order'
-        """
-        return "Standard permutations that are greater than or equal to %s in the Bruhat order"%self.p
-
-    def list(self):
-        r"""
-        Returns a list of permutations greater than or equal to p in the
-        Bruhat order.
-
-        EXAMPLES:
-            sage: Permutations(bruhat_greater=[4,1,2,3]).list()
-            [[4, 1, 2, 3],
-             [4, 1, 3, 2],
-             [4, 2, 1, 3],
-             [4, 2, 3, 1],
-             [4, 3, 1, 2],
-             [4, 3, 2, 1]]
-        """
-        return transitive_ideal(lambda x: x.bruhat_succ(), self.p)
-
-
-################
-# Bruhat Order #
-################
-
-def bruhat_lequal(p1, p2):
-    r"""
-    Returns True if p1 is less than p2in the Bruhat order.
-
-    Algorithm from mupad-combinat.
-
-    EXAMPLES:
-        sage: permutation.bruhat_lequal([2,4,3,1],[3,4,2,1]) 
-        True
-    """
-
-    n1 = len(p1)
-    n2 = len(p2)
-
-    if n1 == 0:
-        return True
-    
-    if p1[0] > p2[0] or p1[n1-1] < p2[n1-1]:
-        return False
-
-    for i in range(n1):
-        c = 0
-        for j in range(n1):
-            if p2[j] > i+1:
-                c += 1
-            if p1[j] > i+1:
-                c -= 1
-            if c < 0:
-                return False
-
-    return True
-
-
-
-#################
-# Permutohedron #
-#################
-
-def permutohedron_lequal(p1, p2, side="right"):
-    r"""
-    Returns True if p1 is less than p2in the permutohedron order.
-
-    By default, the computations are done in the right permutohedron.
-    If you pass the option side='left', then they will be done in the
-    left permutohedron.
-
-
-    EXAMPLES:
-        sage: permutation.permutohedron_lequal(Permutation([3,2,1,4]),Permutation([4,2,1,3]))
-        False
-        sage: permutation.permutohedron_lequal(Permutation([3,2,1,4]),Permutation([4,2,1,3]), side='left')
-        True
-    
-    
-    """
-
-    n1 = len(p1)
-    n2 = len(p2)
-
-    l1 = p1.number_of_inversions()
-    l2 = p2.number_of_inversions()
-
-    if l1 > l2:
-        return Fal
-
-    if side == "right":
-        prod = p1._left_to_right_multiply_on_right(p2.inverse())
-    else:
-        prod = p1._left_to_right_multiply_on_left(p2.inverse())
-
-
-    return prod.number_of_inversions() == l2 - l1
-
-
-############
-# Patterns #
-############
-
-def to_standard(p):
-    r"""
-    Returns a standard permutation corresponding to the
-    permutation p.
-
-    EXAMPLES:
-        sage: permutation.to_standard([4,2,7])
-        [2, 1, 3]
-        sage: permutation.to_standard([1,2,3])
-        [1, 2, 3]
-    """
-
-    s = p[:]
-    biggest = max(p) + 1
-    i = 1
-    for j in range(len(p)):
-        smallest = min(p)
-        smallest_index = p.index(smallest)
-        s[smallest_index] = i
-        i += 1
-        p[smallest_index] = biggest
-
-    return Permutation(s)
-
-
-
-##########################################################
-
-
-def CyclicPermutations(mset):
-    """
-    Returns the combinatorial class of all cyclic permutations of mset in
-    cycle notation.
-    
-    EXAMPLES:
-        sage: CyclicPermutations(range(4)).list()
-        [[0, 1, 2, 3],
-         [0, 1, 3, 2],
-         [0, 2, 1, 3],
-         [0, 2, 3, 1],
-         [0, 3, 1, 2],
-         [0, 3, 2, 1]]
-        sage: CyclicPermutations([1,1,1]).list()
-        [[1, 1, 1]]
-    """
-    return CyclicPermutations_mset(mset)
-
-class CyclicPermutations_mset(CombinatorialClass):
-    def __init__(self, mset):
-        """
-        TESTS:
-            sage: CP = CyclicPermutations(range(4))
-            sage: CP == loads(dumps(CP))
-            True
-        """
-        self.mset = mset
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(CyclicPermutations(range(4)))
-            'Cyclic permutations of [0, 1, 2, 3]'
-        """
-        return "Cyclic permutations of %s"%self.mset
-
-    def list(self, distinct=False):
-        return [p for p in self.iterator(distinct=distinct)]
-
-    def iterator(self, distinct=False):
-        """
-        EXAMPLES:
-            sage: CyclicPermutations(range(4)).list()
-            [[0, 1, 2, 3],
-             [0, 1, 3, 2],
-             [0, 2, 1, 3],
-             [0, 2, 3, 1],
-             [0, 3, 1, 2],
-             [0, 3, 2, 1]]
-             sage: CyclicPermutations([1,1,1]).list()
-             [[1, 1, 1]]
-             sage: CyclicPermutations([1,1,1]).list(distinct=True)
-             [[1, 1, 1], [1, 1, 1]]
-        """
-        if distinct:
-            content = [1]*len(self.mset)
-        else:
-            content = [0]*len(self.mset)
-            index_list = map(self.mset.index, self.mset)
-            for i in index_list:
-                content[i] += 1
-            
-        def label(x):
-            return self.mset[x-1]
-        
-        for necklace in Necklaces(content):
-            yield map(label, necklace)
-
-##########################################3
-
-def CyclicPermutationsOfPartition(partition):
-    """
-    Returns the combinatorial class of all combinations of cyclic permutations of
-    each cell of the partition.
-
-    EXAMPLES:
-        sage: CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]).list()
-        [[[1, 2, 3, 4], [5, 6, 7]],
-         [[1, 2, 4, 3], [5, 6, 7]],
-         [[1, 3, 2, 4], [5, 6, 7]],
-         [[1, 3, 4, 2], [5, 6, 7]],
-         [[1, 4, 2, 3], [5, 6, 7]],
-         [[1, 4, 3, 2], [5, 6, 7]],
-         [[1, 2, 3, 4], [5, 7, 6]],
-         [[1, 2, 4, 3], [5, 7, 6]],
-         [[1, 3, 2, 4], [5, 7, 6]],
-         [[1, 3, 4, 2], [5, 7, 6]],
-         [[1, 4, 2, 3], [5, 7, 6]],
-         [[1, 4, 3, 2], [5, 7, 6]]]
-         
-        sage: CyclicPermutationsOfPartition([[1,2,3,4],[4,4,4]]).list()
-        [[[1, 2, 3, 4], [4, 4, 4]],
-         [[1, 2, 4, 3], [4, 4, 4]],
-         [[1, 3, 2, 4], [4, 4, 4]],
-         [[1, 3, 4, 2], [4, 4, 4]],
-         [[1, 4, 2, 3], [4, 4, 4]],
-         [[1, 4, 3, 2], [4, 4, 4]]]
-         
-        sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list()
-        [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]]]
-        
-        sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True)
-        [[[1, 2, 3], [4, 4, 4]],
-         [[1, 3, 2], [4, 4, 4]],
-         [[1, 2, 3], [4, 4, 4]],
-         [[1, 3, 2], [4, 4, 4]]]
-    """
-    return CyclicPermutationsOfPartition_partition(partition)
-
-class CyclicPermutationsOfPartition_partition(CombinatorialClass):
-    def __init__(self, partition):
-        """
-        TESTS:
-            sage: CP = CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]])
-            sage: CP == loads(dumps(CP))
-            True
-        """
-        self.partition = partition
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]))
-            'Cyclic permutations of partition [[1, 2, 3, 4], [5, 6, 7]]'
-        """
-        return "Cyclic permutations of partition %s"%self.partition
-
-    def iterator(self, distinct=False):
-        """
-        AUTHOR: Robert Miller
-
-        EXAMPLES:
-            sage: CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]).list()
-            [[[1, 2, 3, 4], [5, 6, 7]],
-             [[1, 2, 4, 3], [5, 6, 7]],
-             [[1, 3, 2, 4], [5, 6, 7]],
-             [[1, 3, 4, 2], [5, 6, 7]],
-             [[1, 4, 2, 3], [5, 6, 7]],
-             [[1, 4, 3, 2], [5, 6, 7]],
-             [[1, 2, 3, 4], [5, 7, 6]],
-             [[1, 2, 4, 3], [5, 7, 6]],
-             [[1, 3, 2, 4], [5, 7, 6]],
-             [[1, 3, 4, 2], [5, 7, 6]],
-             [[1, 4, 2, 3], [5, 7, 6]],
-             [[1, 4, 3, 2], [5, 7, 6]]]
-
-            sage: CyclicPermutationsOfPartition([[1,2,3,4],[4,4,4]]).list()
-            [[[1, 2, 3, 4], [4, 4, 4]],
-             [[1, 2, 4, 3], [4, 4, 4]],
-             [[1, 3, 2, 4], [4, 4, 4]],
-             [[1, 3, 4, 2], [4, 4, 4]],
-             [[1, 4, 2, 3], [4, 4, 4]],
-             [[1, 4, 3, 2], [4, 4, 4]]]
-
-            sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list()
-            [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]]]
-
-            sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True)
-            [[[1, 2, 3], [4, 4, 4]],
-             [[1, 3, 2], [4, 4, 4]],
-             [[1, 2, 3], [4, 4, 4]],
-             [[1, 3, 2], [4, 4, 4]]]
-        """
-        
-        if len(self.partition) == 1:
-            for i in CyclicPermutations_mset(self.partition[0]).iterator(distinct=distinct):
-                yield [i]
-        else:
-            for right in CyclicPermutationsOfPartition_partition(self.partition[1:]).iterator(distinct=distinct):
-                for perm in CyclicPermutations_mset(self.partition[0]).iterator(distinct=distinct):
-                    yield [perm] + right
-
-
-    def list(self, distinct=False):
-        """
-        EXAMPLES:
-            sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list()
-            [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]]]
-            sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True)
-            [[[1, 2, 3], [4, 4, 4]],
-             [[1, 3, 2], [4, 4, 4]],
-             [[1, 2, 3], [4, 4, 4]],
-             [[1, 3, 2], [4, 4, 4]]]
-        """
-
-        return [p for p in self.iterator(distinct=distinct)]
Index: age/combinat/permutation_nk.py
===================================================================
--- sage/combinat/permutation_nk.py	(revision 6439)
+++ 	(revision )
@@ -1,108 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.rings.arith import factorial
-import random as rnd
-from sage.combinat.misc import DoublyLinkedList
-
-def count(n,k):
-    """
-    Returns the number of permutations of k things from a list
-    of n things.
-
-    EXAMPLES:
-        sage: permutation_nk.count(3,2)
-        6
-    """
-    return factorial(n)/factorial(n-k)
-
-def iterator(n,k):
-    """
-    An iterator for all permutations of k thinkgs from range(n).
-
-    EXAMPLES:
-        sage: [ p for p in permutation_nk.iterator(3,2)]
-        [[0, 1], [0, 2], [1, 0], [1, 2], [2, 0], [2, 1]]
-
-    """
-    if k == 0:
-        yield []
-        return
-
-    if k>n:
-        return
-
-
-    range_n = range(n)
-    available = range(n)
-    dll = DoublyLinkedList(range_n)
-
-    
-    L = range(k)
-    L[-1] = 'begin'
-    for i in range(k-1):
-        dll.hide(i)
-
-    finished = False
-    while not finished:    
-        L[-1] = dll.next_value[L[-1]]
-        if L[-1] != 'end':
-            yield L[:]
-            continue
-
-        finished = True
-        for i in reversed(range(k-1)):
-            value = L[i]
-            dll.unhide(value)
-            value = dll.next_value[value]
-            if value != 'end':
-                L[i] = value
-                dll.hide(value)
-                value = 'begin'
-                for j in reversed(range(i+1, k-1)):
-                    value = dll.next_value[value]
-                    L[j] = value
-                    dll.hide(value)
-                L[-1] = dll.next_value[value]
-                yield L[:]
-                finished = False
-                break
-
-    return 
-        
-def list(n,k):
-    """
-    Returns a list of all the permutation of k things from range(n).
-
-    EXAMPLES:
-        sage: permutation_nk.list(3,2)
-        [[0, 1], [0, 2], [1, 0], [1, 2], [2, 0], [2, 1]]
-
-    """
-
-    return [c for c in iterator(n,k)]
-
-def random(n,k):
-    """
-    Returns a random permutation of k things from range(n).
-
-    EXAMPLES:
-        sage: permutation_nk.random(3,2) #random
-        [2, 1]
-    """
-    rng = range(n)
-    r = rnd.sample(rng, k)
-        
-    return r
Index: age/combinat/q_analogues.py
===================================================================
--- sage/combinat/q_analogues.py	(revision 6439)
+++ 	(revision )
@@ -1,73 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.misc.misc import prod
-from sage.rings.integer_ring import IntegerRing
-
-def int(n, p=None):
-    """
-    Returns the q-analogue of the integer n.
-
-    If p is unspecified, then it defaults to using
-    the generator q for a univariate polynomial
-    ring over the integers.
-    
-    EXAMPLES:
-        sage: q_analogues.int(3)
-        q^2 + q + 1
-        sage: p = ZZ['p'].0
-        sage: q_analogues.int(3,p)
-        p^2 + p + 1
-    """
-    if p == None:
-        ZZ = IntegerRing()
-        p = ZZ['q'].gens()[0]
-        #pass
-    return sum([p**i for i in range(n)])
-
-def factorial(n, p=None):
-    """
-    Returns the q-analogue of the n!.
-
-    If p is unspecified, then it defaults to using
-    the generator q for a univariate polynomial
-    ring over the integers.
-
-    EXAMPLES:
-        sage: q_analogues.factorial(3)
-        q^3 + 2*q^2 + 2*q + 1
-        sage: p = ZZ['p'].0
-        sage: q_analogues.factorial(3, p)
-        p^3 + 2*p^2 + 2*p + 1
-    """
-    return prod([int(i,p) for i in range(1, n+1)])
-
-def binomial(n,k,p=None):
-    """
-    Returns the q-binomial coefficient.
-
-    If p is unspecified, then it defaults to using
-    the generator q for a univariate polynomial
-    ring over the integers.
-
-    EXAMPLES:
-        sage: q_analogues.binomial(4,2)
-        q^4 + q^3 + 2*q^2 + q + 1
-        sage: p = ZZ['p'].0
-        sage: q_analogues.binomial(4,2,p)
-        p^4 + p^3 + 2*p^2 + p + 1
-    """
-
-    return factorial(n,p)/(factorial(k,p)*factorial(n-k,p))
Index: age/combinat/ranker.py
===================================================================
--- sage/combinat/ranker.py	(revision 6439)
+++ 	(revision )
@@ -1,89 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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/
-#*****************************************************************************
-
-def from_list(l):
-    """
-    Returns a ranker from the list l.
-
-    INPUT:
-        l -- a list
-
-    OUTPUT
-        [rank, unrank] -- functions
-
-    EXAMPLES:
-        sage: l = [1,2,3]
-        sage: r,u = sage.combinat.ranker.from_list(l)
-        sage: r(1)
-        0
-        sage: r(3)
-        2
-        sage: u(2)
-        3
-        sage: u(0)
-        1
-    """
-
-    n = len(l)
-    def unrank(j):
-        if j < 0 or j >= n:
-            raise ValueError, "Argument j ( = %s ) must be between 0 and %d"%(str(j), n)
-
-        return l[j]
-
-    def rank(obj):
-        return l.index(obj)
-
-    return [rank, unrank]
-
-
-def rank_from_list(l):
-    """
-    Returns a rank function given a list l.
-
-    EXAMPLES:
-        sage: l = [1,2,3]
-        sage: r = sage.combinat.ranker.rank_from_list(l)
-        sage: r(1)
-        0
-        sage: r(3)
-        2
-    """
-    def rank(obj):
-        return l.index(obj)
-
-    return rank
-
-
-def unrank_from_list(l):
-    """
-    Returns an unrank function from a list.
-
-    EXAMPLES:
-        sage: l = [1,2,3]
-        sage: u = sage.combinat.ranker.unrank_from_list(l)
-        sage: u(2)
-        3
-        sage: u(0)
-        1
-    """
-    n = len(l)
-    def unrank(j):
-        if j < 0 or j >= n:
-            raise ValueError, "Argument j ( = %s ) must be between 0 and %d"%(str(j), n)
-
-        return l[j]
-
-    return unrank
Index: age/combinat/ribbon.py
===================================================================
--- sage/combinat/ribbon.py	(revision 6439)
+++ 	(revision )
@@ -1,328 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 sage.combinat.misc as misc
-import sage.combinat.skew_tableau
-import sage.combinat.word as word
-import sage.combinat.permutation as permutation
-from combinat import CombinatorialClass, CombinatorialObject
-
-def Ribbon(r):
-    """
-    Returns a ribbon tableau object.
-
-    EXAMPLES:
-        sage: Ribbon([[2,3],[1,4,5]])
-        [[2, 3], [1, 4, 5]]
-    """
-    return Ribbon_class(r)
-        
-class Ribbon_class(CombinatorialObject):
-    def ribbon_shape(self):
-        """
-        Returns the ribbon shape.  The ribbon shape is given
-        just by the number of boxes in each row.
-
-        EXAMPLES:
-            sage: Ribbon([[2,3],[1,4,5]]).ribbon_shape()
-            [2, 3]
-        """
-
-        return [len(row) for row in self]
-
-    def height(self):
-        """
-        Returns the height of the ribbon.
-
-        EXAMPLES:
-            sage: Ribbon([[2,3],[1,4,5]]).height()
-            2
-        """
-        return len(self)
-
-    def width(self):
-        """
-        Returns the width of the ribbon.
-
-        EXAMPLES:
-            sage: Ribbon([[2,3],[1,4,5]]).width()
-            4
-        """
-        return 1+sum([len(r)-1 for r in self])
-
-    def size(self):
-        """
-        Returns the size ( number of boxes ) in the ribbon.
-
-        EXAMPLES:
-            sage: Ribbon([[2,3],[1,4,5]]).size()
-            5
-        """
-        return sum([len(r) for r in self])
-
-    def is_standard(self):
-        """
-        Returns True is the ribbon is standard and False otherwise.
-        ribbon are standard if they are filled with the numbers
-        1...size and they are increasing along both rows and columns.
-
-        EXAMPLES:
-            sage: Ribbon([[2,3],[1,4,5]]).is_standard()
-            True
-            sage: Ribbon([[2,2],[1,4,5]]).is_standard()
-            False
-            sage: Ribbon([[4,5],[1,2,3]]).is_standard()
-            False
-        """
-
-        return self.to_skew_tableau().is_standard()
-
-    def to_skew_tableau(self):
-        """
-        Returns the skew tableau corresponding to the ribbon
-        tableau.
-
-        EXAMPLES:
-            sage: Ribbon([[2,3],[1,4,5]]).to_skew_tableau()
-            [[None, None, 2, 3], [1, 4, 5]]
-        """
-        st = []
-        space_count = 0
-        for row in reversed(self):
-            st.append( [None]*space_count + row )
-            space_count += len(row) - 1
-        st.reverse()
-        return sage.combinat.skew_tableau.SkewTableau(st)
-
-    def to_permutation(self):
-        """
-        Returns the permutation corresponding to the ribbon
-        tableau.
-
-        EXAMPLES:
-            sage: r = Ribbon([[1], [2,3], [4, 5, 6]])
-            sage: r.to_permutation()
-            [1, 2, 3, 4, 5, 6]
-        """
-        return permutation.Permutation(self.to_word())
-    
-    def shape(self):
-        """
-        Returns the skew partition corresponding to the shape of the
-        ribbon.
-
-        EXAMPLES:
-            sage: Ribbon([[2,3],[1,4,5]]).shape()
-            [[4, 3], [2]]
-        """
-        return self.to_skew_tableau().shape()
-
-    def to_word_by_row(self):
-        """
-        Returns a word obtained from a row reading of the ribbon.
-
-        EXAMPLES:
-            sage: Ribbon([[1],[2,3]]).to_word_by_row()
-            [1, 2, 3]
-            sage: Ribbon([[2, 4], [3], [1]]).to_word_by_row()
-            [2, 4, 3, 1]
-        """
-        word = []
-        for row in self:
-            word += row
-
-        return word
-
-
-    def to_word_by_column(self):
-        """
-        Returns the word obtained from a column reading of the ribbon
-
-        EXAMPLES:
-            sage: Ribbon([[1],[2,3]]).to_word_by_column()
-            [2, 1, 3]
-            sage: Ribbon([[2, 4], [3], [1]]).to_word_by_column()
-            [2, 3, 1, 4]      
-
-        """
-        return self.to_skew_tableau().to_word_by_column()
-
-    def to_word(self):
-        """
-        An alias for Ribbon.to_word_by_row().
-
-        EXAMPLES:
-            sage: Ribbon([[1],[2,3]]).to_word_by_row()
-            [1, 2, 3]
-            sage: Ribbon([[2, 4], [3], [1]]).to_word_by_row()
-            [2, 4, 3, 1]
-        """
-        return self.to_word_by_row()
-
-    def evaluation(self):
-        """
-        Returns the evaluation of the word from ribbon.
-
-        EXAMPLES:
-            sage: Ribbon([[1,2],[3,4]]).evaluation()
-            [1, 1, 1, 1]
-        """
-
-        return word.evaluation(self.to_word())
-
-    
-
-def from_shape_and_word(shape, word):
-    """
-    Returns the ribbon corresponding to the given
-    ribbon shape and word.
-
-    EXAMPLES:
-        sage: ribbon.from_shape_and_word([2,3],[1,2,3,4,5])
-        [[1, 2], [3, 4, 5]]
-    """
-    pos = 0
-    r = []
-    for l in shape:
-        r.append(word[pos:pos+l])
-        pos += l
-    return Ribbon(r)
-
-def StandardRibbonTableaux(shape):
-    """
-    Returns the combinatorial class of standard ribbon
-    tableaux of shape shape.
-
-    EXAMPLES:
-        sage: StandardRibbonTableaux([2,2])
-        Standard ribbon tableaux of shape [2, 2]
-        sage: StandardRibbonTableaux([2,2]).first()
-        [[1, 3], [2, 4]]
-        sage: StandardRibbonTableaux([2,2]).last()
-        [[3, 4], [1, 2]]
-        sage: StandardRibbonTableaux([2,2]).count()
-        5
-        sage: StandardRibbonTableaux([2,2]).list()
-        [[[1, 3], [2, 4]],
-         [[1, 4], [2, 3]],
-         [[2, 3], [1, 4]],
-         [[2, 4], [1, 3]],
-         [[3, 4], [1, 2]]]
-
-        sage: StandardRibbonTableaux([2,2]).list()
-        [[[1, 3], [2, 4]],
-         [[1, 4], [2, 3]],
-         [[2, 3], [1, 4]],
-         [[2, 4], [1, 3]],
-         [[3, 4], [1, 2]]]    
-        sage: StandardRibbonTableaux([3,2,2]).count()
-        155
-
-    """
-    return StandardRibbonTableaux_shape(shape)
-
-class StandardRibbonTableaux_shape(CombinatorialClass):
-    def __init__(self, shape):
-        """
-        TESTS:
-            sage: S = StandardRibbonTableaux([2,2])
-            sage: S == loads(dumps(S))
-            True
-        """
-        self.shape = shape
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(StandardRibbonTableaux([2,2]))
-            'Standard ribbon tableaux of shape [2, 2]'
-        """
-        return "Standard ribbon tableaux of shape %s"%self.shape
-
-
-    def first(self):
-        """
-        Returns the first standard ribbon of
-        ribbon shape shape.
-
-        EXAMPLES:
-            sage: StandardRibbonTableaux([2,2]).first()
-            [[1, 3], [2, 4]]
-
-        """
-        return from_permutation(permutation.descents_composition_first(self.shape))
-
-    def last(self):
-        """
-        Returns the first standard ribbon of
-        ribbon shape shape.
-
-        EXAMPLES:
-            sage: StandardRibbonTableaux([2,2]).last()
-            [[3, 4], [1, 2]]
-        """
-        return from_permutation(permutation.descents_composition_last(self.shape))
-
-
-    def iterator(self):
-        """
-        An iterator for the standard ribbon of ribbon
-        shape shape.
-
-        EXAMPLES:
-            sage: [t for t in StandardRibbonTableaux([2,2])]
-            [[[1, 3], [2, 4]],
-             [[1, 4], [2, 3]],
-             [[2, 3], [1, 4]],
-             [[2, 4], [1, 3]],
-             [[3, 4], [1, 2]]]    
-        """
-
-        for p in permutation.descents_composition_list(self.shape):
-            yield from_permutation(p)
-
-def from_permutation(p):
-    """
-    Returns a standard ribbon of size len(p) from a Permutation p.
-    The lengths of each row are given by the distance between the descents
-    of the permutation p.
-    
-    EXAMPLES:
-        sage: [ribbon.from_permutation(p) for p in Permutations(3)]
-        [[[1, 2, 3]],
-         [[1, 3], [2]],
-         [[2], [1, 3]],
-         [[2, 3], [1]],
-         [[3], [1, 2]],
-         [[3], [2], [1]]]
-
-    """
-    if p == []:
-        return Ribbon([])
-    
-    comp = p.descents()
-
-    if comp == []:
-        return Ribbon([p[:]])
-
-    
-    #[p[j]$j=compo[i]+1..compo[i+1]] $i=1..nops(compo)-1, [p[j]$j=compo[nops(compo)]+1..nops(p)]
-    r = [] 
-    r.append([p[j] for j in range(comp[0]+1)])
-    for i in range(len(comp)-1):
-        r.append([ p[j] for j in range(comp[i]+1,comp[i+1]+1) ])
-    r.append( [ p[j] for j in range(comp[-1]+1, len(p))] )
-
-    return Ribbon(r)
Index: age/combinat/schubert_polynomial.py
===================================================================
--- sage/combinat/schubert_polynomial.py	(revision 6439)
+++ 	(revision )
@@ -1,141 +1,0 @@
-
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 combinatorial_algebra import CombinatorialAlgebra, CombinatorialAlgebraElement
-from sage.rings.integer import Integer
-import permutation
-import sage.libs.symmetrica.all as symmetrica
-
-def SchubertPolynomialRing(R):
-    """
-    Returns the Schubert polynomial ring over R on the X basis.
-
-    EXAMPLES:
-        sage: X = SchubertPolynomialRing(ZZ); X
-        Schubert polynomial ring with X basis over Integer Ring
-        sage: X(1)
-        X[1]
-        sage: X([1,2,3])*X([2,1,3])
-        X[2, 1, 3]
-        sage: X([2,1,3])*X([2,1,3])
-        X[3, 1, 2]
-        sage: X([2,1,3])+X([3,1,2,4])
-        X[2, 1, 3] + X[3, 1, 2, 4]
-        sage: a = X([2,1,3])+X([3,1,2,4])
-        sage: a^2
-        X[3, 1, 2] + X[5, 1, 2, 3, 4] + 2*X[4, 1, 2, 3]
-    """
-    return SchubertPolynomialRing_xbasis(R)
-
-def is_SchubertPolynomial(x):
-    """
-    Returns True if x is a Schubert polynomial and False otherwise.
-    
-    EXAMPLES:
-        sage: X = SchubertPolynomialRing(ZZ)
-        sage: a = 1
-        sage: is_SchubertPolynomial(a)
-        False
-        sage: b = X(1)
-        sage: is_SchubertPolynomial(b)
-        True
-        sage: c = X([2,1,3])
-        sage: is_SchubertPolynomial(c)
-        True
-    """
-    return isinstance(x, SchubertPolynomial_class)
-
-class SchubertPolynomial_class(CombinatorialAlgebraElement):
-    def expand(self):
-        """
-        EXAMPLES:
-            sage: X = SchubertPolynomialRing(ZZ)
-            sage: X([2,1,3]).expand()
-            x0
-            sage: map(lambda x: x.expand(), [X(p) for p in Permutations(3)])
-            [1, x0 + x1, x0, x0*x1, x0^2, x0^2*x1]
-        """
-        return symmetrica.t_SCHUBERT_POLYNOM(self)
-
-    def divided_difference(self, i):
-        if isinstance(i, Integer):
-            return symmetrica.divdiff_schubert(i, self)
-        elif i in permutation.Permutations():
-            return symmetrica.divdiff_perm_schubert(i, self)
-        else:
-            raise TypeError, "i must either be an integer or permutation"
-
-    def scalar_product(self, x):
-        """
-        Returns the standard scalar product of self and x.
-
-        EXAMPLES:
-            sage: X = SchubertPolynomialRing(ZZ)
-            sage: a = X([3,2,4,1])
-            sage: a.scalar_product(a)
-            0
-            sage: b = X([4,3,2,1])
-            sage: b.scalar_product(a)
-            X[1, 3, 4, 6, 2, 5, 7]
-            sage: Permutation([1, 3, 4, 6, 2, 5, 7]).to_lehmer_code()
-            [0, 1, 1, 2, 0, 0, 0]
-            sage: s = SFASchur(ZZ)
-            sage: c = s([2,1,1])
-            sage: b.scalar_product(a).expand()
-            x0^2*x1*x2 + x0*x1^2*x2 + x0*x1*x2^2 + x0^2*x1*x3 + x0*x1^2*x3 + x0^2*x2*x3 + 3*x0*x1*x2*x3 + x1^2*x2*x3 + x0*x2^2*x3 + x1*x2^2*x3 + x0*x1*x3^2 + x0*x2*x3^2 + x1*x2*x3^2
-            sage: c.expand(4)
-            x0^2*x1*x2 + x0*x1^2*x2 + x0*x1*x2^2 + x0^2*x1*x3 + x0*x1^2*x3 + x0^2*x2*x3 + 3*x0*x1*x2*x3 + x1^2*x2*x3 + x0*x2^2*x3 + x1*x2^2*x3 + x0*x1*x3^2 + x0*x2*x3^2 + x1*x2*x3^2
-
-        """
-        if is_SchubertPolynomial(x):
-            return symmetrica.scalarproduct_schubert(self, x)
-        else:
-            raise TypeError, "x must be a Schubert polynomial"
-
-    def multiply_variable(self, i):
-        """
-        Returns the Schubert polynomial obtained by multiplying self by
-        the variable x_i.
-
-        EXAMPLES:
-            sage: X = SchubertPolynomialRing(ZZ)
-            sage: a = X([3,2,4,1])
-            sage: a.multiply_variable(0)
-            X[4, 2, 3, 1, 5]
-            sage: a.multiply_variable(1)
-            X[3, 4, 2, 1, 5]
-            sage: a.multiply_variable(2)
-            -X[3, 4, 2, 1, 5] - X[4, 2, 3, 1, 5] + X[3, 2, 5, 1, 4]
-            sage: a.multiply_variable(3)
-            X[3, 2, 4, 5, 1]
-
-        """
-        if isinstance(i, Integer):
-            return symmetrica.mult_schubert_variable(self, i)
-        else:
-            raise TypeError, "i must be an integer"
-        
-
-
-class SchubertPolynomialRing_xbasis(CombinatorialAlgebra):
-    _name = "Schubert polynomial ring with X basis"
-    _prefix = "X"
-    _combinatorial_class = permutation.Permutations()
-    _one = permutation.Permutation([1])
-    _element_class = SchubertPolynomial_class
-    
-    def _multiply_basis(self, left, right):
-        return symmetrica.mult_schubert_schubert(left, right).monomial_coefficients()
Index: age/combinat/set_partition.py
===================================================================
--- sage/combinat/set_partition.py	(revision 6439)
+++ 	(revision )
@@ -1,389 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.sets.set import Set, EnumeratedSet, is_Set
-import sage.combinat.partition as partition
-import sage.rings.integer
-import __builtin__
-import itertools
-from cartesian_product import CartesianProduct
-import sage.combinat.subset as subset
-import sage.combinat.set_partition_ordered as set_partition_ordered
-import copy
-from combinat import CombinatorialClass, CombinatorialObject, bell_number, stirling_number2
-from subword import Subwords
-
-
-def SetPartitions(s, part=None):
-    """
-    An {\it unordered partition} of a set $S$ is a set of pairwise disjoint 
-    nonempty subsets with union $S$ and is represented by a sorted 
-    list of such subsets.
-
-    partitions_set returns the set of all unordered partitions of the 
-    list $S$ of increasing positive integers into k pairwise disjoint 
-    nonempty sets. If k is omitted then all partitions are returned.
-
-    The Bell number $B_n$, named in honor of Eric Temple Bell, is 
-    the number of different partitions of a set with n elements. 
-
-    EXAMPLES:
-        sage: S = [1,2,3,4]
-        sage: SetPartitions(S,2)
-        Set partitions of [1, 2, 3, 4] with 2 parts
-
-         
-    REFERENCES:
-       http://en.wikipedia.org/wiki/Partition_of_a_set
-
-    """
-    if isinstance(s, (int, sage.rings.integer.Integer)):
-        set = range(1, s+1)
-    elif isinstance(s, str):
-        set = [x for x in s]
-    else:
-        set = s
-    
-    if part != None:
-        if isinstance(part, (int, sage.rings.integer.Integer)):
-            if len(set) < part:
-                raise ValueError, "part must be <= len(set)"
-            else:
-                return SetPartitions_setn(set,part)
-        else:
-            if part not in partition.Partitions(len(set)):
-                raise ValueError, "part must be a partition of %s"%len(set)
-            else:
-                return SetPartitions_setparts(set, [partition.Partition(part)])
-    else:
-        return SetPartitions_set(set)
-
-
-
-class SetPartitions_setparts(CombinatorialClass):
-    def __init__(self, set, parts):
-        """
-        TESTS:
-            sage: S = SetPartitions(4, [2,2])
-            sage: S == loads(dumps(S))
-            True
-        """
-        self.set = set
-        self.parts = parts
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitions(4, [2,2]))
-            'Set partitions of [1, 2, 3, 4] with sizes in [[2, 2]]'
-        """
-        return "Set partitions of %s with sizes in %s"%(self.set, self.parts)
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: S = SetPartitions(4, [2,2])
-            sage: all([sp in S for sp in S])
-            True            
-        """
-        #x must be a set
-        if not is_Set(x):
-            return False
-
-        #Make sure that the number of elements match up
-        if sum(map(len, x)) != len(self.set):
-            return False
-
-        #Check to make sure each element of x
-        #is a set
-        u = Set([])
-        for s in x:
-            if not is_Set(s):
-                return False
-            u = u.union(s)
-
-        #Make sure that the union of all the
-        #sets is the original set
-        if u != Set(self.set):
-            return False
-
-        return True
-
-    def count(self):
-        """
-        Returns the number of set partitions of set.  This
-        number is given by the n-th Bell number where n is
-        the number of elements in the set.
-
-        If a partition or partition length is specified, then
-        count will generate all of the set partitions.
-
-        EXAMPLES:
-            sage: SetPartitions([1,2,3,4]).count()
-            15
-            sage: SetPartitions(3).count()
-            5
-            sage: SetPartitions(3,2).count()
-            3
-            sage: SetPartitions([]).count()
-            1
-        """
-        return len(self.list())
-
-
-    def __iterator_part(self, part):
-        set = self.set
-
-        nonzero = []
-        p = partition.Partition(part)
-        expo = p.to_exp()
-
-        for i in range(len(expo)):
-            if expo[i] != 0:
-                nonzero.append([i, expo[i]])
-
-        taillesblocs = map(lambda x: (x[0])*(x[1]), nonzero)
-
-        blocs = set_partition_ordered.OrderedSetPartitions(copy.copy(set), taillesblocs).list()
-
-        for b in blocs:
-            lb = [ _listbloc(nonzero[i][0], nonzero[i][1], b[i]) for i in range(len(nonzero)) ]
-            for x in itertools.imap(lambda x: _union(x), CartesianProduct( *lb )):
-                yield x
-
-
-    
-    def iterator(self):
-        """
-        An iterator for all the set partitions of the set.
-
-        EXAMPLES:
-            sage: SetPartitions(3).list()
-            [{{1, 2, 3}}, {{2, 3}, {1}}, {{1, 3}, {2}}, {{1, 2}, {3}}, {{2}, {3}, {1}}]
-        """
-        for p in self.parts:
-            for sp in self.__iterator_part(p):
-                yield sp
-
-
-class SetPartitions_setn(SetPartitions_setparts):
-    def __init__(self, set, n):
-        """
-        TESTS:
-            sage: S = SetPartitions(5, 3)
-            sage: S == loads(dumps(S))
-            True
-        """
-        self.n = n
-        SetPartitions_setparts.__init__(self, set, partition.Partitions(len(set), length=n).list())
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SetPartitions(5, 3))
-            'Set partitions of [1, 2, 3, 4, 5] with 3 parts'
-        """
-        return "Set partitions of %s with %s parts"%(self.set,self.n)
-
-    def count(self):
-        """
-        The Stirling number of the second kind is the number
-        of partitions of a set of size n into k blocks.
-
-        EXAMPLES:
-            sage: SetPartitions(5, 3).count()
-            25
-            sage: stirling_number2(5,3)
-            25
-        """
-        return stirling_number2(len(self.set), self.n)
-    
-class SetPartitions_set(SetPartitions_setparts):
-    def __init__(self, set):
-        """
-        TESTS:
-            sage: S = SetPartitions([1,2,3])
-            sage: S == loads(dumps(S))
-            True
-        """
-        SetPartitions_setparts.__init__(self, set, partition.Partitions(len(set)))
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr( SetPartitions([1,2,3]) )
-            'Set partitions of [1, 2, 3]'
-        """
-        return "Set partitions of %s"%(self.set)
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: SetPartitions(4).count()
-            15
-            sage: bell_number(4)
-            15
-        """
-        return bell_number(len(self.set))
-
-
-
-def _listbloc(n, nbrepets, listint=None):
-    """
-    listbloc decomposes a set of n*nbrepets integers (the list listint)
-    in nbrepets parts.
-
-    It is used in the algorithm to generate all set partitions.
-
-    Not to be called by the user.
-
-    EXAMPLES:
-        sage: sage.combinat.set_partition._listbloc(2,1)
-        [{{1, 2}}]
-        sage: l = [Set([Set([3, 4]), Set([1, 2])]), Set([Set([2, 4]), Set([1, 3])]), Set([Set([2, 3]), Set([1, 4])])]
-        sage: sage.combinat.set_partition._listbloc(2,2,[1,2,3,4]) == l
-        True
-
-
-    """
-    if isinstance(listint, (int, sage.rings.integer.Integer)) or listint==None:
-        listint = Set(range(1,n+1))
-
-
-    if nbrepets == 1:
-        return [Set([listint])]
-    
-    l = __builtin__.list(listint)
-    l.sort()
-    smallest = Set(l[:1])
-    new_listint = Set(l[1:])
-    
-    f = lambda u, v: u.union(_set_union([smallest,v]))
-    res = []
-    
-    for ssens in subset.Subsets(new_listint, n-1):
-        for z in _listbloc(n, nbrepets-1, new_listint-ssens):
-            res.append(f(z,ssens))
-
-    return res
-
-def _union(s):
-    """
-    TESTS:
-        sage: s = Set([ Set([1,2]), Set([3,4]) ])
-        sage: sage.combinat.set_partition._union(s)
-        {1, 2, 3, 4}
-    """
-    result = Set([])
-    for ss in s:
-        result = result.union(ss)
-    return result
-
-def _set_union(s):
-    """
-    TESTS:
-        sage: s = Set([ Set([1,2]), Set([3,4]) ])
-        sage: sage.combinat.set_partition._set_union(s)
-        {{1, 2, 3, 4}}
-    """
-    result = Set([])
-    for ss in s:
-        result = result.union(ss)
-    return EnumeratedSet([result])
-
-def inf(s,t):
-    """
-    Returns the infimum of the two set partitions s and t.
-
-    EXAMPLES:
-        sage: sp1 = Set([Set([2,3,4]),Set([1])])
-        sage: sp2 = Set([Set([1,3]), Set([2,4])])
-        sage: s = Set([ Set([2,4]), Set([3]), Set([1])]) #{{2, 4}, {3}, {1}}
-        sage: sage.combinat.set_partition.inf(sp1, sp2) == s
-        True
-
-    """
-    temp = [ss.intersection(ts) for ss in s for ts in t]
-    temp = filter(lambda x: x != Set([]), temp)
-    return EnumeratedSet(temp)
-
-def sup(s,t):
-    """
-    Returns the supremum of the two set partitions s and t.
-
-    EXAMPLES:
-        sage: sp1 = Set([Set([2,3,4]),Set([1])])
-        sage: sp2 = Set([Set([1,3]), Set([2,4])])
-        sage: s = Set([ Set([1,2,3,4]) ])
-        sage: sage.combinat.set_partition.sup(sp1, sp2) == s
-        True
-
-    """
-    res = s
-    for p in t:
-        inters = Set(filter(lambda x: x.intersection(p) != Set([]), __builtin__.list(res)))
-        res = res.difference(inters).union(_set_union(inters))
-
-    return res
-
-   
-def standard_form(sp):
-    """
-    Returns the set partition as a list of lists.
-
-    EXAMPLES:
-        sage: map(sage.combinat.set_partition.standard_form, SetPartitions(4, [2,2]))
-        [[[3, 4], [1, 2]], [[2, 4], [1, 3]], [[2, 3], [1, 4]]]
-    """
-
-    return [__builtin__.list(x) for x in sp]
-
-
-def less(s, t):
-    """
-    Returns True if s < t otherwise it returns False.
-
-    EXAMPLES:
-        sage: z = SetPartitions(3).list()
-        sage: sage.combinat.set_partition.less(z[0], z[1])
-        False
-        sage: sage.combinat.set_partition.less(z[4], z[1])
-        True
-        sage: sage.combinat.set_partition.less(z[4], z[0])
-        True
-        sage: sage.combinat.set_partition.less(z[3], z[0])
-        True
-        sage: sage.combinat.set_partition.less(z[2], z[0])
-        True
-        sage: sage.combinat.set_partition.less(z[1], z[0])
-        True
-        sage: sage.combinat.set_partition.less(z[0], z[0])
-        False
-    """
-
-    if _union(s) != _union(t):
-        raise ValueError, "cannont compare partitions of different sets"
-
-    if s == t:
-        return False
-
-    for p in s:
-        f = lambda z: z.intersection(p) != Set([])
-        if len(filter(f, __builtin__.list(t)) ) != 1:
-            return False
-
-    return True
-        
-
Index: age/combinat/set_partition_ordered.py
===================================================================
--- sage/combinat/set_partition_ordered.py	(revision 6439)
+++ 	(revision )
@@ -1,346 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.rings.arith import factorial, binomial
-import itertools
-import __builtin__
-import sage.combinat.composition as composition
-import sage.combinat.word as word
-import sage.combinat.permutation as permutation
-import sage.rings.integer
-from sage.combinat.combinat import stirling_number2
-from sage.sets.set import Set, is_Set
-from combinat import CombinatorialClass, CombinatorialObject
-from sage.misc.misc import prod
-
-
-def OrderedSetPartitions(s, c=None):
-    """
-    Returns the combinatorial class of ordered set partitions
-    of s.
-
-    EXAMPLES:
-        sage: OS = OrderedSetPartitions([1,2,3,4]); OS
-        Ordered set partitions of {1, 2, 3, 4}
-        sage: OS.count()
-        75
-        sage: OS.first()
-        [{1}, {2}, {3}, {4}]
-        sage: OS.last()
-        [{1, 2, 3, 4}]
-        sage: OS.random() #random
-        [{1}, {3}, {2, 4}]
-
-        sage: OS = OrderedSetPartitions([1,2,3,4], [2,2]); OS
-        Ordered set partitions of {1, 2, 3, 4} into parts of size [2, 2]
-        sage: OS.count()
-        6
-        sage: OS.first()
-        [{1, 2}, {3, 4}]
-        sage: OS.last()
-        [{3, 4}, {1, 2}]
-        sage: OS.list()
-        [[{1, 2}, {3, 4}],
-         [{1, 3}, {2, 4}],
-         [{1, 4}, {2, 3}],
-         [{2, 3}, {1, 4}],
-         [{2, 4}, {1, 3}],
-         [{3, 4}, {1, 2}]]
-
-         sage: OS = OrderedSetPartitions("cat"); OS
-         Ordered set partitions of ['c', 'a', 't']
-         sage: OS.list()
-         [[{'a'}, {'c'}, {'t'}],
-          [{'a'}, {'t'}, {'c'}],
-          [{'c'}, {'a'}, {'t'}],
-          [{'t'}, {'a'}, {'c'}],
-          [{'c'}, {'t'}, {'a'}],
-          [{'t'}, {'c'}, {'a'}],
-          [{'a'}, {'c', 't'}],
-          [{'c'}, {'a', 't'}],
-          [{'t'}, {'a', 'c'}],
-          [{'a', 'c'}, {'t'}],
-          [{'a', 't'}, {'c'}],
-          [{'c', 't'}, {'a'}],
-          [{'a', 'c', 't'}]]
-    """
-    if isinstance(s, (int, sage.rings.integer.Integer)):
-        if s < 0:
-            raise ValueError, "s must be non-negative"
-        set = Set(range(1, s+1))
-    elif isinstance(s, str):
-        set = [x for x in s]
-    else:
-        set = Set(s)
-        
-    if c is None:
-        return OrderedSetPartitions_s(set)
-    else:
-        if isinstance(c, (int, sage.rings.integer.Integer)):
-            return OrderedSetPartitions_sn(set, c)
-        elif c not in composition.Compositions(len(set)):
-            raise ValueError, "c must be a composition of %s"%len(set)
-        else:
-            return OrderedSetPartitions_scomp(set,c)
-        
-
-class OrderedSetPartitions_s(CombinatorialClass):
-    def __init__(self, s):
-        """
-        TESTS:
-            sage: OS = OrderedSetPartitions([1,2,3,4])
-            sage: OS == loads(dumps(OS))
-            True
-        """
-        self.s = s
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(OrderedSetPartitions([1,2,3,4]))
-            'Ordered set partitions of {1, 2, 3, 4}'
-        """
-        return "Ordered set partitions of %s"%self.s
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: OS = OrderedSetPartitions([1,2,3,4])
-            sage: all([sp in OS for sp in OS])
-            True
-        """
-        #x must be a list
-        if not isinstance(x, list):
-            return False
-
-        #The total number of elements in the list
-        #should be the same as the number is self.s
-        if sum(map(len, x)) != len(self.s):
-            return False
-
-        #Check to make sure each element of the list
-        #is a set
-        u = Set([])
-        for s in x:
-            if not is_Set(s):
-                return False
-            u = u.union(s)
-
-        #Make sure that the union of all the
-        #sets is the original set
-        if u != Set(self.s):
-            return False
-
-        return True
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: OrderedSetPartitions(0).count()
-            1
-            sage: OrderedSetPartitions(1).count()
-            1
-            sage: OrderedSetPartitions(2).count()
-            3
-            sage: OrderedSetPartitions(3).count()
-            13
-            sage: OrderedSetPartitions([1,2,3]).count()
-            13
-            sage: OrderedSetPartitions(4).count()
-            75
-            sage: OrderedSetPartitions(5).count()
-            541
-        """
-        set = self.s
-        return sum([factorial(k)*stirling_number2(len(set),k) for k in range(len(set)+1)])
-
-
-
-    def iterator(self):
-        """
-        EXAMPLES:
-            sage: OrderedSetPartitions([1,2,3]).list()
-            [[{1}, {2}, {3}],
-             [{1}, {3}, {2}],
-             [{2}, {1}, {3}],
-             [{3}, {1}, {2}],
-             [{2}, {3}, {1}],
-             [{3}, {2}, {1}],
-             [{1}, {2, 3}],
-             [{2}, {1, 3}],
-             [{3}, {1, 2}],
-             [{1, 2}, {3}],
-             [{1, 3}, {2}],
-             [{2, 3}, {1}],
-             [{1, 2, 3}]]
-        """
-        for x in composition.Compositions(len(self.s)):
-            for z in OrderedSetPartitions(self.s,x):
-                yield z
-
-
-class OrderedSetPartitions_sn(CombinatorialClass):
-    def __init__(self, s, n):
-        """
-        TESTS:
-            sage: OS = OrderedSetPartitions([1,2,3,4], 2)
-            sage: OS == loads(dumps(OS))
-            True
-        """
-        self.s = s
-        self.n = n
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: OS = OrderedSetPartitions([1,2,3,4], 2)
-            sage: all([sp in OS for sp in OS])
-            True
-            sage: OS.count()
-            14
-            sage: len(filter(lambda x: x in OS, OrderedSetPartitions([1,2,3,4])))
-            14
-        """
-        return x in OrderedSetPartitions_s(self.s) and len(x) == self.n
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(OrderedSetPartitions([1,2,3,4], 2))
-            'Ordered set partitions of {1, 2, 3, 4} into 2 parts'
-        """
-        return "Ordered set partitions of %s into %s parts"%(self.s,self.n)
-
-    def count(self):
-        """
-
-        EXAMPLES:
-            sage: OrderedSetPartitions(4,2).count()
-            14
-            sage: OrderedSetPartitions(4,1).count()
-            1
-
-        """
-        set = self.s
-        n   = self.n
-        return factorial(n)*stirling_number2(len(set),n)
-
-    def iterator(self):
-        """
-        EXAMPLES:
-            sage: OrderedSetPartitions([1,2,3,4], 2).list()
-            [[{1}, {2, 3, 4}],
-             [{2}, {1, 3, 4}],
-             [{3}, {1, 2, 4}],
-             [{4}, {1, 2, 3}],
-             [{1, 2}, {3, 4}],
-             [{1, 3}, {2, 4}],
-             [{1, 4}, {2, 3}],
-             [{2, 3}, {1, 4}],
-             [{2, 4}, {1, 3}],
-             [{3, 4}, {1, 2}],
-             [{1, 2, 3}, {4}],
-             [{1, 2, 4}, {3}],
-             [{1, 3, 4}, {2}],
-             [{2, 3, 4}, {1}]]
-        """
-        for x in composition.Compositions(len(self.s),length=self.n):
-            for z in OrderedSetPartitions_scomp(self.s,x):
-                yield z
-
-class OrderedSetPartitions_scomp(CombinatorialClass):
-    def __init__(self, s, comp):
-        """
-        TESTS:
-            sage: OS = OrderedSetPartitions([1,2,3,4], [2,1,1])
-            sage: OS == loads(dumps(OS))
-            True
-        """
-        self.s = s
-        self.c = composition.Composition(comp)
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(OrderedSetPartitions([1,2,3,4], [2,1,1]))
-            'Ordered set partitions of {1, 2, 3, 4} into parts of size [2, 1, 1]'
-        """
-        return "Ordered set partitions of %s into parts of size %s"%(self.s,self.c)
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: OS = OrderedSetPartitions([1,2,3,4], [2,1,1])
-            sage: all([ sp in OS for sp in OS])
-            True
-            sage: OS.count()
-            12
-            sage: len(filter(lambda x: x in OS, OrderedSetPartitions([1,2,3,4])))
-            12
-        """
-        return x in OrderedSetPartitions_s(self.s) and map(len, x) == self.c
-    
-    def count(self):
-        """
-        EXAMPLES:
-            sage: OrderedSetPartitions(5,[2,3]).count()
-            10
-            sage: OrderedSetPartitions(0, []).count()
-            1
-            sage: OrderedSetPartitions(0, [0]).count()
-            1
-            sage: OrderedSetPartitions(0, [0,0]).count()
-            1
-            sage: OrderedSetPartitions(5, [2,0,3]).count()
-            10
-        """
-        return factorial(len(self.s))/prod([factorial(i) for i in self.c])
-    
-    def iterator(self):
-        """
-        TESTS:
-            sage: OrderedSetPartitions([1,2,3,4], [2,1,1]).list()
-            [[{1, 2}, {3}, {4}],
-             [{1, 2}, {4}, {3}],
-             [{1, 3}, {2}, {4}],
-             [{1, 4}, {2}, {3}],
-             [{1, 3}, {4}, {2}],
-             [{1, 4}, {3}, {2}],
-             [{2, 3}, {1}, {4}],
-             [{2, 4}, {1}, {3}],
-             [{3, 4}, {1}, {2}],
-             [{2, 3}, {4}, {1}],
-             [{2, 4}, {3}, {1}],
-             [{3, 4}, {2}, {1}]]
-        """
-        comp = self.c
-        lset = [x for x in self.s]
-        l = len(self.c)
-        dcomp = [-1] + comp.descents(final_descent=True)
-
-        def f(perm):
-            res = permutation.Permutation(range(1,len(lset)))*word.standard(perm).inverse()
-            res = map(lambda x: lset[x-1], res)
-            return [ Set( res[dcomp[i]+1:dcomp[i+1]+1] ) for i in range(l)]
-
-        p = []
-        for j in range(l):
-            p += [j+1]*comp[j]
-
-        for x in permutation.Permutations(p):
-            yield f(x)
-
-
-
Index: age/combinat/sfa.py
===================================================================
--- sage/combinat/sfa.py	(revision 6439)
+++ 	(revision )
@@ -1,981 +1,0 @@
-r"""
-Symmetric Functions
-
-AUTHOR: Mike Hansen, 2007-06-15
-
-sage: s = SymmetricFunctionAlgebra(QQ, basis='schur')
-sage: e = SymmetricFunctionAlgebra(QQ, basis='elementary')
-sage: f1 = s([2,1])
-sage: f1
-s[2, 1]
-sage: f2 = e(f1)
-sage: f2
-e[2, 1] - e[3]
-sage: f1 == f2
-False
-sage: f1.expand(3, alphabet=['x','y','z'])
-x^2*y + x*y^2 + x^2*z + 2*x*y*z + y^2*z + x*z^2 + y*z^2
-sage: f2.expand(3, alphabet=['x','y','z'])
-x^2*y + x*y^2 + x^2*z + 2*x*y*z + y^2*z + x*z^2 + y*z^2
-
-
-sage: m = SFAMonomial(QQ)
-sage: m([3,1])
-m[3, 1]
-sage: m(4)
-4*m[]
-sage: m([4])
-m[4]
-sage: 3*m([3,1])-1/2*m([4])
-3*m[3, 1] - 1/2*m[4]
-
-
-Code needs to be added to coerce symmetric polynomials into symmetric functions.
-
-sage: p = SFAPower(QQ)
-sage: m = p(3)
-sage: m
-3*p[]
-sage: m.parent()
-Symmetric Algebra over Rational Field, Power symmetric functions as basis
-sage: m + p([3,2])
-3*p[] + p[3, 2]
-
-
-sage: s = SFASchur(QQ)
-sage: h = SFAHomogeneous(QQ)
-sage: P = SFAPower(QQ)
-sage: e = SFAElementary(QQ)
-sage: m = SFAMonomial(QQ)
-sage: a = s([3,1])
-sage: s(a)
-s[3, 1]
-sage: h(a)
-h[3, 1] - h[4]
-sage: p(a)
-1/8*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] - 1/8*p[2, 2] - 1/4*p[4]
-sage: e(a)
-e[2, 1, 1] - e[2, 2] - e[3, 1] + e[4]
-sage: m(a)
-3*m[1, 1, 1, 1] + 2*m[2, 1, 1] + m[2, 2] + m[3, 1]
-sage: a.expand(4)
-x0^3*x1 + x0^2*x1^2 + x0*x1^3 + x0^3*x2 + 2*x0^2*x1*x2 + 2*x0*x1^2*x2 + x1^3*x2 + x0^2*x2^2 + 2*x0*x1*x2^2 + x1^2*x2^2 + x0*x2^3 + x1*x2^3 + x0^3*x3 + 2*x0^2*x1*x3 + 2*x0*x1^2*x3 + x1^3*x3 + 2*x0^2*x2*x3 + 3*x0*x1*x2*x3 + 2*x1^2*x2*x3 + 2*x0*x2^2*x3 + 2*x1*x2^2*x3 + x2^3*x3 + x0^2*x3^2 + 2*x0*x1*x3^2 + x1^2*x3^2 + 2*x0*x2*x3^2 + 2*x1*x2*x3^2 + x2^2*x3^2 + x0*x3^3 + x1*x3^3 + x2*x3^3
-
-
-sage: h(m([1]))
-h[1]
-sage: h( m([2]) +m([1,1]) )
-h[2]
-sage: h( m([3]) + m([2,1]) + m([1,1,1]) )
-h[3]
-sage: h( m([4]) + m([3,1]) + m([2,2]) + m([2,1,1]) + m([1,1,1,1]) )
-h[4]
-sage: k = 5
-sage: h( sum([ m(part) for part in Partitions(k)]) )
-h[5]
-sage: k = 10
-sage: h( sum([ m(part) for part in Partitions(k)]) )
-h[10]
-
-#Print style
-sage: P3 = Partitions(3)
-sage: P3.list()
-[[3], [2, 1], [1, 1, 1]]
-sage: m = SFAMonomial(QQ)
-sage: f = sum([m(p) for p in P3])
-sage: m.get_print_style()
-'lex'
-sage: f
-m[1, 1, 1] + m[2, 1] + m[3]
-sage: m.set_print_style('length')
-sage: f
-m[3] + m[2, 1] + m[1, 1, 1]
-sage: m.set_print_style('maximal_part')
-sage: f
-m[1, 1, 1] + m[2, 1] + m[3]
-
-
-sage: s = SFASchur(QQ)
-sage: m = SFAMonomial(QQ)
-sage: m([3])*s([2,1])
-2*m[3, 1, 1, 1] + m[3, 2, 1] + 2*m[4, 1, 1] + m[4, 2] + m[5, 1]
-sage: s(m([3])*s([2,1]))
-s[2, 1, 1, 1, 1] - s[2, 2, 2] - s[3, 3] + s[5, 1]
-sage: s(s([2,1])*m([3]))
-s[2, 1, 1, 1, 1] - s[2, 2, 2] - s[3, 3] + s[5, 1]
-sage: e = SFAElementary(QQ)
-sage: e([4])*e([3])*e([1])
-e[4, 3, 1]
-
-
-sage: s = SFASchur(QQ)
-sage: z = s([2,1]) + s([1,1,1])
-sage: z.coefficient([2,1])
-1
-sage: z.length()
-2
-sage: z.support()
-[[[1, 1, 1], [2, 1]], [1, 1]]
-sage: z.degree()
-3
-
-
-
-
-"""
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.rings.ring import Ring
-from sage.rings.integer import Integer
-
-from sage.algebras.algebra import Algebra
-
-import partition
-import skew_partition
-import sage.structure.parent_gens
-import sage.libs.symmetrica.all as symmetrica
-from sage.matrix.constructor import matrix
-
-from sage.rings.integer_ring import IntegerRing
-from sage.rings.rational_field import RationalField
-
-from sage.misc.misc import repr_lincomb
-from sage.algebras.algebra_element import AlgebraElement
-
-from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
-
-import operator
-
-ZZ = IntegerRing()
-QQ = RationalField()
-
-translate = {'monomial':'MONOMIAL', 'homogeneous':'HOMSYM', 'power':'POWSYM', 'elementary':'ELMSYM', 'schur':'SCHUR'}
-        
-def SymmetricFunctionAlgebra(R, basis="schur"):
-    """
-    Return the free algebra over the ring $R$ on $n$ generators with
-    given names.
-
-    INPUT:
-        R -- ring with identity
-        basis
-
-    OUTPUT:
-        A SymmetricFunctionAlgebra 
-
-    EXAMPLES:
-    """
-    if basis == 'schur' or basis == 's':
-        return cache_s(R)
-    elif basis == "elementary" or  basis ==  'e':
-        return cache_e(R)
-    elif basis == "homogeneous" or basis ==  'h':
-        return cache_h(R)
-    elif basis == 'power' or basis ==  'p':
-        return cache_p(R)
-    elif basis == 'monomial' or basis ==  'm':
-        return cache_m(R)
-    else:
-        raise ValueError, "unknown basis (= %s)"%basis
-
-def SFAPower(R):
-    return SymmetricFunctionAlgebra(R, basis='power')
-def SFAElementary(R):
-    return SymmetricFunctionAlgebra(R, basis='elementary')
-def SFAHomogeneous(R):
-    return SymmetricFunctionAlgebra(R, basis='homogeneous')
-def SFASchur(R):
-    return SymmetricFunctionAlgebra(R, basis='schur')
-def SFAMonomial(R):
-    return SymmetricFunctionAlgebra(R, basis='monomial')
-
-def is_SymmetricFunctionAlgebra(x):
-    """
-    Return True if x is a symmetric function algebra; otherwise, return False.
-
-    EXAMPLES:
-        sage: sage.combinat.sfa.is_SymmetricFunctionAlgebra(5)
-        False
-        sage: sage.combinat.sfa.is_SymmetricFunctionAlgebra(ZZ)
-        False
-        sage: sage.combinat.sfa.is_SymmetricFunctionAlgebra(SymmetricFunctionAlgebra(ZZ,'schur'))
-        True    
-    """
-    return isinstance(x, SymmetricFunctionAlgebra_generic)
-
-
-class SymmetricFunctionAlgebra_generic(Algebra):
-    """
-    EXAMPLES:
-    """
-    def __init__(self, R, basis, element_class, prefix):
-        """
-        INPUT:
-            R -- ring
-        """
-        if not isinstance(R, Ring):
-            raise TypeError, "Argument R must be a ring."
-        try:
-            z = R(Integer(1))
-        except:
-            raise ValueError, "R must have a unit element"
-        
-        self.__basis = basis
-        self.__element_class = element_class
-        self.__prefix = prefix
-        self.__print_style = 'lex'
-        sage.structure.parent_gens.ParentWithGens.__init__(self, R, None)
-
-    def __call__(self, x):
-        """
-        Coerce x into self.
-        """
-        R = self.base_ring()
-        eclass = self.__element_class
-        if isinstance(x, int):
-            x = Integer(x)
-
-        #same basis
-        if isinstance(x, eclass):
-            P = x.parent()
-            #same base ring
-            if P is self:
-                return x
-            #different base ring
-            else:
-                return eclass(self, dict([ (e1,R(e2)) for e1,e2 in x._monomial_coefficients.items()]))
-        #symmetric function, but different basis
-        elif is_SymmetricFunction(x):
-            R = self.base_ring()
-            xP = x.parent()
-            xm = x.monomial_coefficients()
-           
-            #determine the conversion function.
-            try:
-                t = eval('symmetrica.t_' + translate[xP.basis()] + '_' +  translate[self.basis()])
-            except AttributeError:
-                raise TypeError, "do not know how to convert from %s to %s"%(xP.basis(), self.basis())
-
-            z_elt = {}
-            
-            for part in xm:
-                if xm[part] == R(0):
-                    continue
-                xmprime = t( {part:Integer(1)} ).monomial_coefficients()
-                for part2 in xmprime:
-                    z_elt[part2] = z_elt.get(part2, R(0)) + xmprime[part2]*R(xm[part])
-            z = self(Integer(0))
-            z._monomial_coefficients = z_elt
-            return z
-
-        elif x in partition.Partitions():
-            return eclass(self, {partition.Partition(x):R(1)})
-        elif x in skew_partition.SkewPartitions():
-            skewschur = symmetrica.part_part_skewschur(x[0], x[1])
-            return self(skewschur)
-        elif isinstance(x, list):
-            if len(x) == 2 and isinstance(x[0], list) and isinstance(x[1], list):
-                skewschur = symmetrica.part_part_skewschur(x[0], x[1])
-                return self(skewschur)
-            else:
-                return eclass(self, {partition.Partition(x):R(1)})
-        elif x.parent() is R:
-            return eclass(self, {partition.Partition([]):x})
-        elif R.has_coerce_map_from(x.parent()):
-            return eclass(self, {partition.Partition([]):R(x)})
-        else:
-            try:
-                return eclass(self, {Partition([]):self.base_ring()(x)})
-            except:
-                raise TypeError, "do not know how to make x (= %s) an element of self"%(x)
-
-    def basis(self):
-        return self.__basis
-
-    def is_field(self):
-        if self.__ngens == 0:
-            return self.base_ring().is_field()
-        return False
-
-    def is_commutative(self):
-        """
-        Return True if this symmetric function algebra is commutative.
-
-        EXAMPLES:
-        
-        """
-        return self.__ngens <= 1 and self.base_ring().is_commutative()
-
-    def _an_element_impl(self):
-        return self.__element_class(self, {partition.Partition([]):self.base_ring()(0)})
-
-    def __cmp__(self, other):
-        """
-        Two free algebras are considered the same if they have the
-        same base ring, number of generators and variable names.
-
-        EXAMPLES:
-
-        """
-        if not isinstance(other, SymmetricFunctionAlgebra_generic):
-            return -1
-        c = cmp(self.base_ring(), other.base_ring())
-        if c: return c
-        c = cmp(self.__basis, other.__basis)
-        if c: return c
-        return 0
-
-    def get_print_style(self):
-        return self.__print_style
-    
-    def set_print_style(self, ps):
-        styles = ['lex', 'length', 'maximal_part']
-        if ps not in styles:
-            raise ValueError, "the print style must be one of ", styles
-        self.__print_style = ps
-
-    def _repr_(self):
-        """
-        Text representation of this symmetric function algebra.
-
-        EXAMPLES:
-        """
-        return "Symmetric Algebra over %s, %s symmetric functions as basis"%(
-            self.base_ring(), self.__basis.capitalize())
-
-    #def _corece_impl(self, x):
-    #     raise NotImplementedError
-    def _coerce_impl(self, x):
-        try:
-            R = x.parent()
-            #Coerce other symmetric functions in
-            if is_SymmetricFunctionAlgebra(R):
-                #Only perform the coercion if we can go from the base
-                #ring of x to the base ring of self
-                if self.base_ring().has_coerce_map_from( R.base_ring() ):
-                    return self(x)
-        except AttributeError:
-            pass
-        
-        # any ring that coerces to the base ring of this free algebra.
-        return self._coerce_try(x, [self.base_ring()])
-                                
-    def ngens(self):
-        """
-        The number of generators of the algebra.
-
-        EXAMPLES:
-        """
-        return infinity
-
-    def prefix(self):
-        return self.__prefix
-
-    def transition_matrix(self, basis, n):
-        """
-        Returns the transitions matrix.
-        
-        EXAMPLES:
-            sage: s = SFASchur(QQ)
-            sage: m = SFAMonomial(QQ)
-            sage: s.transition_matrix(m,5)
-            [1 1 1 1 1 1 1]
-            [0 1 1 2 2 3 4]
-            [0 0 1 1 2 3 5]
-            [0 0 0 1 1 3 6]
-            [0 0 0 0 1 2 5]
-            [0 0 0 0 0 1 4]
-            [0 0 0 0 0 0 1]
-
-            sage: p = SFAPower(QQ)
-            sage: s.transition_matrix(p, 4)
-            [ 1/4  1/3  1/8  1/4 1/24]
-            [-1/4    0 -1/8  1/4  1/8]
-            [   0 -1/3  1/4    0 1/12]
-            [ 1/4    0 -1/8 -1/4  1/8]
-            [-1/4  1/3  1/8 -1/4 1/24]
-            sage: StoP = s.transition_matrix(p,4)
-            sage: a = s([3,1])+5*s([1,1,1,1])-s([4])
-            sage: a
-            5*s[1, 1, 1, 1] + s[3, 1] - s[4]
-            sage: mon, coef = a.support()
-            sage: coef
-            [5, -1, 1]
-            sage: mon
-            [[1, 1, 1, 1], [4], [3, 1]]
-            sage: cm = matrix([[-1,1,0,0,5]])
-            sage: cm * StoP
-            [-7/4  4/3  3/8 -5/4 7/24]
-            sage: p(a)
-            7/24*p[1, 1, 1, 1] - 5/4*p[2, 1, 1] + 3/8*p[2, 2] + 4/3*p[3, 1] - 7/4*p[4]
-
-
-            sage: h = SFAHomogeneous(QQ)
-            sage: e = SFAElementary(QQ)
-            sage: s.transition_matrix(m,7) == h.transition_matrix(s,7).transpose()
-            True
-
-            sage: h.transition_matrix(m, 7) == h.transition_matrix(m, 7).transpose()
-            True
-
-            sage: h.transition_matrix(e, 7) == e.transition_matrix(h, 7)
-            True
-
-            
-            sage: p.transition_matrix(s, 5)
-            [ 1 -1  0  1  0 -1  1]
-            [ 1  0 -1  0  1  0 -1]
-            [ 1 -1  1  0 -1  1 -1]
-            [ 1  1 -1  0 -1  1  1]
-            [ 1  0  1 -2  1  0  1]
-            [ 1  2  1  0 -1 -2 -1]
-            [ 1  4  5  6  5  4  1]
-           
-            sage: e.transition_matrix(m,7) == e.transition_matrix(m,7).transpose()
-            True
-
-
-        """
-        P = partition.Partitions(n)
-        Plist = P.list()
-
-        m = []
-        
-        for row_part in Plist:
-            z = basis(self(row_part))
-            m.append( map( lambda col_part: z.coefficient(col_part), Plist ) )
-        return matrix(m)
-
-
-class SymmetricFunctionAlgebra_schur(SymmetricFunctionAlgebra_generic):
-    def __init__(self, R):
-        SymmetricFunctionAlgebra_generic.__init__(self, R, "schur", SymmetricFunctionAlgebraElement_schur, 's')
-    def is_schur_basis(self):
-        return True
- 
-    
-
-class SymmetricFunctionAlgebra_monomial(SymmetricFunctionAlgebra_generic):
-    def __init__(self, R):
-        SymmetricFunctionAlgebra_generic.__init__(self, R, "monomial", SymmetricFunctionAlgebraElement_monomial, 'm')
-
-class SymmetricFunctionAlgebra_elementary(SymmetricFunctionAlgebra_generic):
-    def __init__(self, R):
-        SymmetricFunctionAlgebra_generic.__init__(self, R, "elementary", SymmetricFunctionAlgebraElement_elementary, 'e')        
-
-class SymmetricFunctionAlgebra_power(SymmetricFunctionAlgebra_generic):
-    def __init__(self, R):
-        SymmetricFunctionAlgebra_generic.__init__(self, R, "power", SymmetricFunctionAlgebraElement_power, 'p')
-
-class SymmetricFunctionAlgebra_homogeneous(SymmetricFunctionAlgebra_generic):
-    def __init__(self, R):
-        SymmetricFunctionAlgebra_generic.__init__(self, R, "homogeneous", SymmetricFunctionAlgebraElement_homogeneous, 'h')
-                    
-from sage.misc.cache import Cache
-cache_s = Cache(SymmetricFunctionAlgebra_schur)
-cache_m = Cache(SymmetricFunctionAlgebra_monomial)
-cache_p = Cache(SymmetricFunctionAlgebra_power)
-cache_e = Cache(SymmetricFunctionAlgebra_elementary)
-cache_h = Cache(SymmetricFunctionAlgebra_homogeneous)
-
-
-
-############
-# Elements #
-############
-
-
-def is_SymmetricFunction(x):
-    return isinstance(x, SymmetricFunctionAlgebraElement_generic)
-
-
-class SymmetricFunctionAlgebraElement_generic(AlgebraElement):
-    """
-    A symmetric function element.
-    """
-    def __init__(self, A, x):
-        """
-        Create a symmetric function x.  This should never be called directly, but only through the
-        symmetric function algebra's __call__ method.
-        """
-        AlgebraElement.__init__(self, A)
-        self._monomial_coefficients = x
-
-    def __call__(self, x):
-        """
-        Plethysm.
-
-        This is inefficient right now as it not only does it term by term, it also converts both arguments
-        into the schur basis before computing the plethysm.
-
-        EXAMPLES:
-            sage: s = SFASchur(QQ)
-            sage: h = SFAHomogeneous(QQ)
-            sage: s ( h([3])( h([2]) ) )
-            s[2, 2, 2] + s[4, 2] + s[6]
-            sage: p = SFAPower(QQ)
-            sage: p([3])( s([2,1]) )
-            1/3*p[3, 3, 3] - 1/3*p[9]
-            sage: e = SFAElementary(QQ)
-            sage: e([3])( e([2]) )
-            e[3, 3] + e[4, 1, 1] - 2*e[4, 2] - e[5, 1] + e[6]
-        
-        """
-
-        if not is_SymmetricFunction(x):
-            raise TypeError, "only know how to compute plethysms between symmetric functions"
-
-        R = self.parent().base_ring()
-        s = SFASchur(R)
-
-        if self.parent().basis() == 'schur':
-            self_schur = self
-        else:
-            self_schur = s(self)
-
-        if x.parent().basis() == 'schur':
-            x_schur = x
-        else:
-            x_schur = s(x)
-
-
-        self_mcs = self_schur.monomial_coefficients()
-        x_mcs    = x_schur.monomial_coefficients()
-
-        z_elt = {}
-        
-
-        for self_part in self_mcs:
-            for x_part in x_mcs:
-                scalar = self_mcs[self_part]*x_mcs[x_part]
-                plet = symmetrica.schur_schur_plet(self_part, x_part)
-                plet_mcs = plet.monomial_coefficients()
-                for plet_part in plet_mcs:
-                    z_elt[ plet_part ] = z_elt.get( plet_part, R(0)) + plet_mcs[plet_part]*scalar
-
-        z = s(0)
-        z._monomial_coefficients = z_elt
-
-        if self.parent().basis() == 'schur':
-            return z
-        else:
-            return self.parent()(z)
-
-    def monomial_coefficients(self):
-        return self._monomial_coefficients
-    
-    def _repr_(self):
-        v = self._monomial_coefficients.items()
-
-        ps = self.parent().get_print_style()
-        if ps == 'lex':
-            v.sort(key=lambda x: x[0])
-        if ps == 'length':
-            v.sort(key=lambda x: len(x[0]))
-        if ps == 'maximal_part':
-            def lmax(x):
-                if x[0] == []:
-                    return 0
-                else:
-                    return max(x[0])
-            v.sort(key=lmax)
-            
-        prefix = self.parent().prefix()
-        mons = [ prefix + str(m) for (m, _) in v ]
-        cffs = [ x for (_, x) in v ]
-        x = repr_lincomb(mons, cffs).replace("*1 "," ")
-        if x[len(x)-2:] == "*1":
-            return x[:len(x)-2]
-        else:
-            return x
-
-    def _latex_(self):
-        v = self._monomial_coefficients.items()
-
-        ps = self.parent().get_print_style()
-        if ps == 'lex':
-            v.sort(key=lambda x: x[0])
-        if ps == 'length':
-            v.sort(key=lambda x: len(x[0]))
-        if ps == 'maximal_part':
-            def lmax(x):
-                if x[0] == []:
-                    return 0
-                else:
-                    return max(x[0])
-            v.sort(key=lmax)
-            
-        prefix = self.parent().prefix()
-        mons = [ prefix + '_{' + ",".join(map(str, m)) + '}' for (m, _) in v ]
-        cffs = [ x for (_, x) in v ]
-        x = repr_lincomb(mons, cffs, is_latex=True).replace("*1 "," ")
-        if x[len(x)-2:] == "*1":
-            return x[:len(x)-2]
-        else:
-            return x        
-
-    def __cmp__(left, right):
-        """
-        Compare two symmetric functions with the same parents.
-
-        The ordering is the one on the underlying sorted list of (monomial,coefficients) pairs.
-
-        EXAMPLES:
-        """
-        v = left._monomial_coefficients.items()
-        v.sort()
-        w = right._monomial_coefficients.items()
-        w.sort()
-        return cmp(v, w)
-
-    def _add_(self, y):
-        A = self.parent()
-        z_elt = dict(self._monomial_coefficients)
-        for m, c in y._monomial_coefficients.iteritems():
-            if z_elt.has_key(m):
-                cm = z_elt[m] + c
-                if cm == 0:
-                    del z_elt[m]
-                else:
-                    z_elt[m] = cm
-            else:
-                z_elt[m] = c
-        z = A(Integer(0))
-        z._monomial_coefficients = z_elt
-        return z
-
-    def _neg_(self):
-        y = self.parent()(0)
-        y_elt = {}
-        for m, c in self._monomial_coefficients.iteritems():
-            y_elt[m] = -c
-        y._monomial_coefficients = y_elt
-        return y
-
-    def _sub_(self, y):
-        A = self.parent()
-        z_elt = dict(self._monomial_coefficients)
-        for m, c in y._monomial_coefficients.iteritems():
-            if z_elt.has_key(m):
-                cm = z_elt[m] - c
-                if cm == 0:
-                    del z_elt[m]
-                else:
-                    z_elt[m] = cm
-            else:
-                z_elt[m] = -c
-        z = A(Integer(0))
-        z._monomial_coefficients = z_elt
-        return z
-                        
-    def _mul_(self, y):
-        raise NotImplementedError
-
-    def __pow__(self, n):
-        """
-        EXAMPLES:
-            sage: s = SFASchur(QQ)
-            sage: z = s([2,1])
-            sage: z
-            s[2, 1]
-            sage: z^2
-            s[2, 2, 1, 1] + s[2, 2, 2] + s[3, 1, 1, 1] + 2*s[3, 2, 1] + s[3, 3] + s[4, 1, 1] + s[4, 2]
-
-            sage: e = SFAElementary(QQ)
-            sage: y = e([1])
-            sage: y^2
-            e[1, 1]
-            sage: y^4
-            e[1, 1, 1, 1]
-        """
-        if not isinstance(n, (int, Integer)):
-            raise TypeError, "n must be an integer"
-        A = self.parent()
-        z = A(Integer(1))
-        for i in range(n):
-            z *= self
-        return z
-
-    def coefficient(self, m):
-        """
-        EXAMPLES:
-            sage: s = SFASchur(QQ)
-            sage: z = s([4]) - 2*s([2,1]) + s([1,1,1]) + s([1])
-            sage: z.coefficient([4])
-            1
-            sage: z.coefficient([2,1])
-            -2
-        """        
-        if isinstance(m, partition.Partition_class):
-            return self._monomial_coefficients.get(m, self.parent().base_ring()(0))
-        elif m in partition.Partitions():
-            return self._monomial_coefficients[partition.Partition(m)]
-        else:
-            raise TypeError, "you must specify a partition"
-
-    def __len__(self):
-        return self.length()
-    
-    def length(self):
-        """
-        EXAMPLES:
-            sage: s = SFASchur(QQ)
-            sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1])
-            sage: z.length()
-            4
-        """
-        return len( filter(lambda x: self._monomial_coefficients[x] != 0, self._monomial_coefficients) )
-
-    def support(self):
-        """
-        EXAMPLES:
-            sage: s = SFASchur(QQ)
-            sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1])
-            sage: z.support()
-            [[[4], [1, 1, 1], [1], [2, 1]], [1, 1, 1, 1]]
-        """
-        v = self._monomial_coefficients.items()
-        mons = [ m for (m, _) in v ]
-        cffs = [ x for (_, x) in v ]
-        return [mons, cffs]
-
-    def degree(self):
-        """
-        EXAMPLES:
-            sage: s = SFASchur(QQ)
-            sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) + 3
-            sage: z.degree()
-            4
-        """
-        return max( map( sum, self._monomial_coefficients ) )
-
-    def restrict_degree(self, d, exact=True):
-        """
-        EXAMPLES:
-            sage: s = SFASchur(QQ)
-            sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1])
-            sage: z.restrict_degree(2)
-            0
-            sage: z.restrict_degree(1)
-            s[1]
-            sage: z.restrict_degree(3)
-            s[1, 1, 1] + s[2, 1]
-            sage: z.restrict_degree(3, exact=False)
-            s[1] + s[1, 1, 1] + s[2, 1]
-        """
-        res = self.parent()(0)
-        if exact:
-            res._monomial_coefficients = dict( filter( lambda x: sum(x[0]) == d, self._monomial_coefficients.items()) )
-        else:
-            res._monomial_coefficients = dict( filter( lambda x: sum(x[0]) <= d, self._monomial_coefficients.items()) )
-        return res
-
-    def restrict_partition_lengths(self, l, exact=True):
-        """
-
-        EXAMPLES:
-            sage: s = SFASchur(QQ)
-            sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1])
-            sage: z.restrict_partition_lengths(2)
-            s[2, 1]
-            sage: z.restrict_partition_lengths(2, exact=False)
-            s[1] + s[2, 1] + s[4]
-        """
-        res = self.parent()(0)
-        if exact:
-            res._monomial_coefficients = dict( filter( lambda x: len(x[0]) == l, self._monomial_coefficients.items()) )
-        else:
-            res._monomial_coefficients = dict( filter( lambda x: len(x[0]) <= l, self._monomial_coefficients.items()) )
-        return res
-
-    def restrict_parts(self, n):
-        """
-
-        EXAMPLES:
-            sage: s = SFASchur(QQ)
-            sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1])
-            sage: z.restrict_parts(2)
-            s[1] + s[1, 1, 1] + s[2, 1]
-            sage: z.restrict_parts(1)
-            s[1] + s[1, 1, 1]
-        """
-        def lmax(x):
-            """Return 0 as the max of an empty list."""
-            if x[0] == []:
-                return 0
-            else:
-                return max(x[0])
-        res = self.parent()(0)
-        res._monomial_coefficients = dict( filter( lambda x: lmax(x) <= n, self._monomial_coefficients.items()) )
-        return res        
-
-    def expand(self, n, alphabet='x'):
-        """
-        Expands the symmetric function as a symmetric polynomial in n variables.
-
-        EXAMPLES:
-            sage: s = SFASchur(QQ)
-            sage: a = s([2,1])
-            sage: a.expand(2)
-            x0^2*x1 + x0*x1^2
-            sage: a.expand(3)
-            x0^2*x1 + x0*x1^2 + x0^2*x2 + 2*x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2
-            sage: a.expand(4)
-            x0^2*x1 + x0*x1^2 + x0^2*x2 + 2*x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2 + x0^2*x3 + 2*x0*x1*x3 + x1^2*x3 + 2*x0*x2*x3 + 2*x1*x2*x3 + x2^2*x3 + x0*x3^2 + x1*x3^2 + x2*x3^2
-            sage: a.expand(2, alphabet='y')
-            y0^2*y1 + y0*y1^2
-            sage: a.expand(2, alphabet=['a','b'])
-            a^2*b + a*b^2
-
-            sage: p = SFAPower(QQ)
-            sage: a = p([2])
-            sage: a.expand(2)
-            x0^2 + x1^2
-            sage: a.expand(3, alphabet=['a','b','c'])
-            a^2 + b^2 + c^2
-            sage: p([2,1,1]).expand(2)
-            x0^4 + 2*x0^3*x1 + 2*x0^2*x1^2 + 2*x0*x1^3 + x1^4
-        """
-        e = eval('symmetrica.compute_' + str(translate[self.parent().basis()]).lower() + '_with_alphabet')
-        resPR = PolynomialRing(self.parent().base_ring(), n, alphabet)
-        res = resPR(0)
-        self_mc = self._monomial_coefficients
-        for part in self_mc:
-            res += self_mc[part] * resPR(e(part, n, alphabet))
-        return res
-
-    def frobenius(self):
-        raise NotImplementedError
-
-    def scalar(self):
-        raise NotImplementedError
-
-
-
-class SymmetricFunctionAlgebraElement_ehp(SymmetricFunctionAlgebraElement_generic):
-    def _mul_(left, right):
-        A = left.parent()
-        R = A.base_ring()
-        z_elt = {}
-        for (left_m, left_c) in left._monomial_coefficients.iteritems():
-            for (right_m, right_c) in right._monomial_coefficients.iteritems():
-                m = list(left_m)+list(right_m)
-                m.sort(reverse=True)
-                m = partition.Partition(m)
-                if m in z_elt:
-                    z_elt[ m ] = z_elt[m] + left_c * right_c
-                else:
-                    z_elt[ m ] = left_c * right_c
-        z = A(Integer(0))
-        z._monomial_coefficients = z_elt
-        return z
-
-
-
-class SymmetricFunctionAlgebraElement_schur(SymmetricFunctionAlgebraElement_generic):
-    def _mul_(left, right):
-        #Use symmetrica to do the multiplication
-        A = left.parent()
-        R = A.base_ring()
-
-        if  R is ZZ or R is QQ:
-            return symmetrica.mult_schur_schur(left, right)
-
-        z_elt = {}
-        for (left_m, left_c) in left._monomial_coefficients.iteritems():
-            for (right_m, right_c) in right._monomial_coefficients.iteritems():
-                d = symmetrica.mult_schur_schur({left_m:Integer(1)}, {right_m:Integer(1)})
-                for m in d:
-                    if m in z_elt:
-                        z_elt[ m ] = z_elt[m] + left_c * right_c * d[m]
-                    else:
-                        z_elt[ m ] = left_c * right_c * d[m]
-        z = A(Integer(0))
-        z._monomial_coefficients = z_elt
-        return z
-
-    def frobenius(self):
-        parent = self.parent()
-        z = {}
-        mcs = self.monomial_coefficients()
-        for part in mcs:
-            z[part.conjugate()] = mcs[part]
-        res = parent(0)
-        res._monomial_coefficients = z
-        return res
-
-            
-
-        
-
-class SymmetricFunctionAlgebraElement_monomial(SymmetricFunctionAlgebraElement_generic):
-    def _mul_(left, right):
-        #Use symmetrica to do the multiplication
-        A = left.parent()
-        R = A.base_ring()
-
-        if  R is ZZ or R is QQ:
-            return symmetrica.mult_monomial_monomial(left, right)
-
-        z_elt = {}
-        for (left_m, left_c) in left._monomial_coefficients.iteritems():
-            for (right_m, right_c) in right._monomial_coefficients.iteritems():
-                d = symmetrica.mult_monomial_monomial({left_m:Integer(1)}, {right_m:Integer(1)})
-                for m in d:
-                    if m in z_elt:
-                        z_elt[ m ] = z_elt[m] + left_c * right_c * d[m]
-                    else:
-                        z_elt[ m ] = left_c * right_c * d[m]
-        z = A(Integer(0))
-        z._monomial_coefficients = z_elt
-        return z
-
-    def frobenius(self):
-        parent = self.parent()
-        s = SFASchur(parent.base_ring())
-        return parent(s(self).frobenius())
-
-class SymmetricFunctionAlgebraElement_elementary(SymmetricFunctionAlgebraElement_ehp):
-    def frobenius(self):
-        base_ring = self.parent().base_ring()
-        h = SFAHomogeneous(base_ring)
-        mcs = self.monomial_coefficients()
-        res = h(0)
-        res._monomial_coefficients = mcs
-        return res
-
-class SymmetricFunctionAlgebraElement_homogeneous(SymmetricFunctionAlgebraElement_ehp):
-    def frobenius(self):
-        base_ring = self.parent().base_ring()
-        e = SFAElementary(base_ring)
-        mcs = self.monomial_coefficients()
-        res = e(0)
-        res._monomial_coefficients = mcs
-        return res
-
-class SymmetricFunctionAlgebraElement_power(SymmetricFunctionAlgebraElement_ehp):
-    def frobenius(self):
-        parent = self.parent()
-        base_ring = parent.base_ring()
-        z = {}
-        mcs = self.monomial_coefficients()
-        for part in mcs:
-            z[part] = (-1)**(sum(part)-len(part))*mcs[part]
-        res = parent(0)
-        res._monomial_coefficients = z
-        return res
-
-
Index: age/combinat/skew_partition.py
===================================================================
--- sage/combinat/skew_partition.py	(revision 6439)
+++ 	(revision )
@@ -1,717 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 sage.combinat.composition
-import sage.combinat.partition
-import sage.combinat.misc as misc
-import sage.combinat.generator as generator
-from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
-from sage.rings.all import QQ, ZZ
-from sage.sets.set import Set
-from sage.graphs.graph import DiGraph
-from UserList import UserList
-from combinat import CombinatorialClass, CombinatorialObject
-import sfa
-from sage.matrix.matrix_space import MatrixSpace
-from sage.rings.infinity import PlusInfinity
-infinity = PlusInfinity()
-
-def SkewPartition(skp):
-    """
-    Returns the skew partition object corresponding to skp.
-
-    EXAMPLES:
-        sage: skp = SkewPartition([[3,2,1],[2,1]]); skp
-        [[3, 2, 1], [2, 1]]
-        sage: skp.inner()
-        [2, 1]
-        sage: skp.outer()
-        [3, 2, 1]
-    """
-    if skp not in SkewPartitions():
-        raise ValueError, "invalid skew partition"
-    else:
-        return SkewPartition_class(skp)
-
-class SkewPartition_class(CombinatorialObject):
-    def __init__(self, skp):
-        """
-        TESTS:
-            sage: skp = SkewPartition([[3,2,1],[2,1]])
-            sage: skp == loads(dumps(skp))
-            True
-        """
-        outer = sage.combinat.partition.Partition(skp[0])
-        inner = sage.combinat.partition.Partition(skp[1])
-        CombinatorialObject.__init__(self, [outer, inner])
-
-    def inner(self):
-        """
-        Returns the inner partition of the skew partition.
-
-        EXAMPLES:
-            sage: SkewPartition([[3,2,1],[1,1]]).inner()
-            [1, 1]
-        """
-        return self[1]
-
-    def outer(self):
-        """
-        Returns the outer partition of the skew partition.
-
-        EXAMPLES:
-            sage: SkewPartition([[3,2,1],[1,1]]).outer()
-            [3, 2, 1]
-        """        
-        return self[0]
-     
-    
-
-    def row_lengths(self):
-        """
-        Returns the sum of the row lengths of the skew partition.
-
-        EXAMPLES:
-            sage: SkewPartition([[3,2,1],[1,1]]).row_lengths()
-            [2, 1, 1]
-
-        """
-        skp = self
-        o = skp[0]
-        i = skp[1]+[0]*(len(skp[0])-len(skp[1]))
-        return [x[0]-x[1] for x in zip(o,i)]
-
-
-    def size(self):
-        """
-        Returns the size of the skew partition.
-
-        EXAMPLES:
-            sage: SkewPartition([[3,2,1],[1,1]]).size()
-            4
-        """
-        return sum(self.row_lengths())
-
-
-
-    def conjugate(self):
-        """
-        Returns the conjugate of the skew partition skp.
-
-        EXAMPLES:
-            sage: SkewPartition([[3,2,1],[2]]).conjugate()
-            [[3, 2, 1], [1, 1]]
-        """
-        return SkewPartition(map(lambda x: x.conjugate(), self))
-
-
-    def outer_corners(self):
-        """
-        Returns a list of the outer corners of the skew partition skp.
-
-        EXAMPLES:
-            sage: SkewPartition([[4, 3, 1], [2]]).outer_corners()
-            [[0, 3], [1, 2], [2, 0]]
-        """
-        return self.outer().corners()
-
-
-    def inner_corners(self):
-        """
-        Returns a list of the inner corners of the skew partition skp.
-
-        EXAMPLES:
-            sage: SkewPartition([[4, 3, 1], [2]]).inner_corners()
-            [[0, 2], [1, 0]]
-        """
-        
-        inner = self.inner()
-        outer = self.outer()
-        if inner == []:
-            if outer == []:
-                return []
-            else:
-                return [[0,0]]
-        icorners = [[0, inner[0]]]
-        nn = len(inner)
-        for i in range(1,nn):
-            if inner[i] != inner[i-1]:
-                icorners += [ [i, inner[i]] ]
-
-        icorners += [[nn, 0]]
-        return icorners
-
-
-
-    def to_dag(self):
-        """
-        Returns a directed acyclic graph corresponding to the
-        skew partition.
-
-        EXAMPLES:
-            sage: dag = SkewPartition([[3, 2, 1], [1, 1]]).to_dag()
-            sage: dag.arcs()
-            [('0,1', '0,2', None), ('0,1', '1,1', None)]
-            sage: dag.vertices()
-            ['0,1', '0,2', '1,1', '2,0']
-        """
-        i = 0
-
-        #Make the skew tableau from the shape
-        skew = [[1]*row_length for row_length in self.outer()]
-        inner = self.inner()
-        for i in range(len(inner)):
-            for j in range(inner[i]):
-                skew[i][j] = None
-
-        G = DiGraph()
-        for row in range(len(skew)):
-            for column in range(len(skew[row])):
-                if skew[row][column] != None:
-                    string = "%d,%d" % (row, column)
-                    G.add_vertex(string)
-                    #Check to see if there is a node to the right
-                    if column != len(skew[row]) - 1:
-                        newstring = "%d,%d" % (row, column+1)
-                        G.add_arc(string, newstring)
-
-                    #Check to see if there is anything below
-                    if row != len(skew) - 1:
-                        if len(skew[row+1]) > column:
-                            if skew[row+1][column] != None:
-                                newstring = "%d,%d" % (row+1, column)
-                                G.add_arc(string, newstring)
-        return G
-
-
-##     def r_quotient(self, k):
-##         """
-##         The quotient map extended to skew partitions.
-
-##         """
-##         ## k-th element is the skew partition built using the k-th partition of the
-##         ## k-quotient of the outer and the inner partition.
-##         ## This bijection is only defined if the inner and the outer partition
-##         ## have the same core
-##         if self.inner().r_core(k) == self.outer().r_core(k):
-##             rQinner = self.inner().r_quotient(k)
-##             rQouter = self.outer().r_quotient(k)
-##             return 
-
-    def rows_intersection_set(self):
-        """
-        Returns the set of boxes in the lines of lambda which intersect the
-        skew partition. 
-
-        EXAMPLES:
-            sage: skp = SkewPartition([[3,2,1],[2,1]])
-            sage: boxes = Set([ (0,0), (0, 1), (0,2), (1, 0), (1, 1), (2, 0)])
-            sage: skp.rows_intersection_set() == boxes
-            True
-        """
-        res = []
-        outer = self.outer()
-        inner = self.inner()
-        inner += [0] * int(len(outer)-len(inner))
-
-        for i in range(len(outer)):
-            for j in range(outer[i]):
-                if outer[i] != inner[i]:
-                    res.append((i,j))
-        return Set(res)
-
-    def columns_intersection_set(self):
-        """
-        Returns the set of boxes in the lines of lambda which intersect the
-        skew partition. 
-
-        EXAMPLES:
-            sage: skp = SkewPartition([[3,2,1],[2,1]])
-            sage: boxes = Set([ (0,0), (0, 1), (0,2), (1, 0), (1, 1), (2, 0)])
-            sage: skp.columns_intersection_set() == boxes
-            True
-        """
-        res = [ (x[1], x[0]) for x in self.conjugate().rows_intersection_set()]
-        return Set(res)
-
-
-    def pieri_macdonald_coeffs(self):
-        """
-        Computation of the coefficients which appear in the Pieri formula
-        for Macdonald polynomails given in his book ( Chapter 6.6
-        formula 6.24(ii) )
-
-        EXAMPLES:
-            sage: SkewPartition([[3,2,1],[2,1]]).pieri_macdonald_coeffs()
-            1
-            sage: SkewPartition([[3,2,1],[2,2]]).pieri_macdonald_coeffs()
-            (q^2*t^3 - q^2*t - t^2 + 1)/(q^2*t^3 - q*t^2 - q*t + 1)
-            sage: SkewPartition([[3,2,1],[2,2,1]]).pieri_macdonald_coeffs()
-            (q^6*t^8 - q^6*t^6 - q^4*t^7 - q^5*t^5 + q^4*t^5 - q^3*t^6 + q^5*t^3 + 2*q^3*t^4 + q*t^5 - q^3*t^2 + q^2*t^3 - q*t^3 - q^2*t - t^2 + 1)/(q^6*t^8 - q^5*t^7 - q^5*t^6 - q^4*t^6 + q^3*t^5 + 2*q^3*t^4 + q^3*t^3 - q^2*t^2 - q*t^2 - q*t + 1)
-            sage: SkewPartition([[3,3,2,2],[3,2,2,1]]).pieri_macdonald_coeffs()
-            (q^5*t^6 - q^5*t^5 + q^4*t^6 - q^4*t^5 - q^4*t^3 + q^4*t^2 - q^3*t^3 - q^2*t^4 + q^3*t^2 + q^2*t^3 - q*t^4 + q*t^3 + q*t - q + t - 1)/(q^5*t^6 - q^4*t^5 - q^3*t^4 - q^3*t^3 + q^2*t^3 + q^2*t^2 + q*t - 1)
-        """
-        
-        set_prod = self.rows_intersection_set() - self.columns_intersection_set()
-        res = 1
-        for s in set_prod:
-            res *= self.inner().arms_legs_coeff(s[0],s[1])
-            res /= self.outer().arms_legs_coeff(s[0],s[1])
-        return res
-
-    def k_conjugate(self, k):
-        """
-        Returns the k-conjugate of the skew partition.
-
-        EXAMPLES:
-            sage: SkewPartition([[3,2,1],[2,1]]).k_conjugate(3)
-            [[2, 1, 1, 1, 1], [2, 1]]
-            sage: SkewPartition([[3,2,1],[2,1]]).k_conjugate(4)
-            [[2, 2, 1, 1], [2, 1]]
-            sage: SkewPartition([[3,2,1],[2,1]]).k_conjugate(5)
-            [[3, 2, 1], [2, 1]]
-        """
-        return SkewPartition([ self.outer().k_conjugate(k), self.inner().k_conjugate(k) ])
-
-    def jacobi_trudy(self):
-        """
-        EXAMPLES:
-            sage: SkewPartition([[3,2,1],[2,1]]).jacobi_trudy()
-            [h[1]    0    0]
-            [h[3] h[1]    0]
-            [h[5] h[3] h[1]]
-            sage: SkewPartition([[4,3,2],[2,1]]).jacobi_trudy()
-            [h[2]  h[]    0]
-            [h[4] h[2]  h[]]
-            [h[6] h[4] h[2]]
-        """
-        p = self.outer()
-        q = self.inner()
-        if len(p) == 0 and len(q) == 0:
-            return MatrixSpace(sfa.SFAHomogeneous(QQ), 0)(0)
-        nn = len(p)
-        h = sfa.SFAHomogeneous(QQ)
-        H = MatrixSpace(h, nn)
-
-        q  = q + [0]*int(nn-len(q))
-        m = []
-        for i in range(1,nn+1):
-            row = []
-            for j in range(1,nn+1):
-                v = p[j-1]-q[i-1]-j+i
-                if v < 0:
-                    row.append(h(0))
-                else:
-                    row.append(h([v]))
-            m.append(row)
-        return H(m)
-
-    def overlap(self):
-        """
-        """
-        return overlap_aux(self)
-
-def overlap_aux(skp):
-    """
-    Returns the overlap of the skew partition skp.
-
-    EXAMPLES:
-        sage: overlap = sage.combinat.skew_partition.overlap_aux
-        sage: overlap([[],[]])
-        +Infinity
-        sage: overlap([[1],[]])
-        +Infinity
-        sage: overlap([[10],[2]])
-        +Infinity
-        sage: overlap([[10,1],[2]])
-        -1
-    """
-    p,q = skp
-    if len(p) <= 1:
-        return infinity
-    if q == []:
-        return min(p)
-    r = [ q[0] ] + q
-    return min(rowlengths_aux([p,r]))
-
-def rowlengths_aux(skp):
-    """
-
-    """
-    if skp[0] == []:
-        return []
-    else:
-        return map(lambda x: x[0] - x[1], zip(skp[0], skp[1]))
-
-def SkewPartitions(n=None, row_lengths=None, overlap=0):
-    """
-    Returns the combinatorial class of skew partitions.
-
-    EXAMPLES:
-    """
-    number_of_arguments = 0
-    for arg in ['n', 'row_lengths']:
-        if eval(arg) != None:
-            number_of_arguments += 1
-
-    if number_of_arguments > 1:
-        raise ValueError, "you can only specify one of n or row_lengths"
-
-    if number_of_arguments == 0:
-        return SkewPartitions_all()
-    
-    if n != None:
-        return SkewPartitions_n(n, overlap)
-    else:
-        return SkewPartitions_rowlengths(row_lengths, overlap)
-
-class SkewPartitions_all(CombinatorialClass):
-    def __init__(self):
-        """
-        TESTS:
-            sage: S = SkewPartitions()
-            sage: S == loads(dumps(S))
-            True
-        """
-        pass
-    
-    object_class = SkewPartition_class
-    
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: [[], []] in SkewPartitions()
-            True
-            sage: [[], [1]] in SkewPartitions()
-            False
-            sage: [[], [-1]] in SkewPartitions()
-            False
-            sage: [[], [0]] in SkewPartitions()
-            False
-            sage: [[3,2,1],[]] in SkewPartitions()
-            True
-            sage: [[3,2,1],[1]] in SkewPartitions()
-            True
-            sage: [[3,2,1],[2]] in SkewPartitions()
-            True
-            sage: [[3,2,1],[3]] in SkewPartitions()
-            True
-            sage: [[3,2,1],[4]] in SkewPartitions()
-            False            
-            sage: [[3,2,1],[1,1]] in SkewPartitions()
-            True
-            sage: [[3,2,1],[1,2]] in SkewPartitions()
-            False
-            sage: [[3,2,1],[2,1]] in SkewPartitions()
-            True
-            sage: [[3,2,1],[2,2]] in SkewPartitions()
-            True
-            sage: [[3,2,1],[3,2]] in SkewPartitions()
-            True
-            sage: [[3,2,1],[1,1,1]] in SkewPartitions()
-            True
-            sage: [[7, 4, 3, 2], [8, 2, 1]] in SkewPartitions()
-            False
-            sage: [[7, 4, 3, 2], [5, 2, 1]] in SkewPartitions()
-            True
-        """
-        if isinstance(x, SkewPartition_class):
-            return True
-        
-        try:
-            if len(x) != 2:
-                return False
-        except:
-            return False
-
-        p = sage.combinat.partition.Partitions()
-        if x[0] not in p:
-            return False
-        if x[1] not in p:
-            return False
-
-        if not sage.combinat.partition.Partition(x[0]).dominates(x[1]):
-            return False
-
-        return True
-        
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SkewPartitions())
-            'Skew partitions'
-        """
-        return "Skew partitions"
-    
-    def list(self):
-        """
-        TESTS:
-            sage: SkewPartitions().list()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError
-        """
-        raise NotImplementedError
-
-class SkewPartitions_n(CombinatorialClass):
-    def __init__(self, n, overlap=0):
-        """
-        TESTS:
-            sage: S = SkewPartitions(3)
-            sage: S == loads(dumps(S))
-            True
-            sage: S = SkewPartitions(3, overlap=1)
-            sage: S == loads(dumps(S))
-            True
-        """
-        self.n = n
-        if overlap == 'connected':
-            self.overlap = 1
-        else:
-            self.overlap = overlap
-            
-    object_class = SkewPartition_class
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: [[],[]] in SkewPartitions(0)
-            True
-            sage: [[3,2,1], []] in SkewPartitions(6)
-            True
-            sage: [[3,2,1], []] in SkewPartitions(7)
-            False
-            sage: [[3,2,1], []] in SkewPartitions(5)
-            False
-            sage: [[7, 4, 3, 2], [8, 2, 1]] in SkewPartitions(8)
-            False
-            sage: [[7, 4, 3, 2], [5, 2, 1]] in SkewPartitions(8)
-            False
-            sage: [[7, 4, 3, 2], [5, 2, 1]] in SkewPartitions(5)
-            False
-            sage: [[7, 4, 3, 2], [5, 2, 1]] in SkewPartitions(5, overlap=-1)
-            False
-            sage: [[7, 4, 3, 2], [5, 2, 1]] in SkewPartitions(8, overlap=-1)
-            True
-            sage: [[7, 4, 3, 2], [5, 2, 1]] in SkewPartitions(8, overlap=0)
-            False
-            sage: [[7, 4, 3, 2], [5, 2, 1]] in SkewPartitions(8, overlap='connected')
-            False
-            sage: [[7, 4, 3, 2], [5, 2, 1]] in SkewPartitions(8, overlap=-2)
-            True
-            
-        """
-        return x in SkewPartitions() and sum(x[0])-sum(x[1]) == self.n and self.overlap <= overlap_aux(x)
-
-    
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SkewPartitions(3))
-            'Skew partitions of 3'
-            sage: repr(SkewPartitions(3, overlap=1))
-            'Skew partitions of 3 with overlap of 1'
-        """
-        string = "Skew partitions of %s"%self.n
-        if self.overlap:
-            string += " with overlap of %s"%self.overlap
-        return string
-    
-    
-    def _count_slide(self, co, overlap=0):
-        """
-        // auxiliary function for count
-        // count_slide(compo, overlap) counts all the skew partitions related to
-        // the composition co by 'sliding'. (co has is the list of rowLengths).
-        // See fromRowLengths_aux function and note that if connected, skew partitions
-        // are nn = min(ck_1, ck)-1 but the for loop begins in step 0.
-        // The skew partitions are unconnected if overlap = 0 (default case).
-        """
-        nn = len(co)
-        result = 1
-        for i in range(nn-1):
-            comb    = min(co[i], co[i+1])
-            comb   += 1 - overlap
-            result *= comb
-
-        return result
-
-    def count(self):
-        """
-        Returns the number of skew partitions of the integer n.
-
-        EXAMPLES:
-        """
-        n = self.n
-        overlap = self.overlap
-        
-        if n == 0:
-            return 1
-
-        if overlap > 0:
-            gg = sage.combinat.composition.Compositions(n, min_part = overlap).iterator()
-        else:
-            gg = sage.combinat.composition.Compositions(n).iterator()
-
-        sum_a = 0
-        for co in gg:
-            sum_a += self._count_slide(co, overlap=overlap)
-
-        return sum_a
-
-    def list(self):
-        """
-        Returns a list of the skew partitions of n.
-
-        EXAMPLES:
-            sage: SkewPartitions(3).list()
-            [[[1, 1, 1], []],
-             [[2, 2, 1], [1, 1]],
-             [[2, 1, 1], [1]],
-             [[3, 2, 1], [2, 1]],
-             [[2, 2], [1]],
-             [[3, 2], [2]],
-             [[2, 1], []],
-             [[3, 1], [1]],
-             [[3], []]]
-            sage: SkewPartitions(3, overlap=0).list()
-            [[[1, 1, 1], []],
-             [[2, 2, 1], [1, 1]],
-             [[2, 1, 1], [1]],
-             [[3, 2, 1], [2, 1]],
-             [[2, 2], [1]],
-             [[3, 2], [2]],
-             [[2, 1], []],
-             [[3, 1], [1]],
-             [[3], []]]
-            sage: SkewPartitions(3, overlap=1).list()
-            [[[1, 1, 1], []], [[2, 2], [1]], [[2, 1], []], [[3], []]]
-            sage: SkewPartitions(3, overlap=2).list()
-            [[[3], []]]
-            sage: SkewPartitions(3, overlap=3).list()
-            [[[3], []]]
-            sage: SkewPartitions(3, overlap=4).list()
-            []
-
-        """
-        n = self.n
-        overlap = self.overlap
-
-        result = []
-        for co in sage.combinat.composition.Compositions(n, min_part=overlap).list():
-            result += SkewPartitions(row_lengths=co, overlap=overlap).list()
-
-        return result
-    
-######################################
-# Skew Partitions (from row lengths) #
-######################################
-class SkewPartitions_rowlengths(CombinatorialClass):
-    """
-    The combinatorial class of all skew partitions with
-    given row lengths.
-    
-    """
-    def __init__(self, co, overlap=0):
-        """
-        TESTS:
-            sage: S = SkewPartitions(row_lengths=[2,1])
-            sage: S == loads(dumps(S))
-            True
-        """
-        self.co = co
-        if overlap == 'connected':
-            self.overlap = 1
-        else:
-            self.overlap = overlap
-
-    object_class = SkewPartition_class
-    
-    def __contains__(self, x):
-        valid = x in SkewPartitions()
-        if valid:
-            o = x[0]
-            i = x[1]+[0]*(len(x[0])-len(x[1]))
-            return [x[0]-x[1] for x in zip(o,i)] == self.co
-    
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SkewPartitions(row_lengths=[2,1]))
-            'Skew partitions with row lengths [2, 1]'
-        """
-        return "Skew partitions with row lengths %s"%self.co
-
-    def _from_row_lengths_aux(self, sskp, ck_1, ck, overlap=0):
-        """
-        // auxiliary function for fromRowLengths
-        // fromRowLengths_aux(skp, ck_1, ck, overlap) is a step in the computation of
-        // the skew partitions related to the composition [c1,c2,..ck-1,ck].
-        // skp corresponds to a skew partition related to [c1,c2,..ck-1],
-        // and fromRowLengths_aux computes all the possibilities when sliding part
-        // 'ck' added to the top of skp. (old 'slide function')
-        // The skew partitions are unconnected if overlap = 0 (default case).
-
-        """
-        lskp = []
-        nn = min(ck_1, ck)
-        mm = max(0, ck-ck_1)
-        # nn should be >= 0.  In the case of the positive overlap,
-        # the min_part condition insures ck>=overlap for all k
-
-        nn -= overlap
-        for i in range(nn+1):
-            (skp1, skp2) = sskp
-            skp2 += [0]*(len(skp1)-len(skp2))
-            skp1 = map(lambda x: x + i + mm, skp1)
-            skp1 += [ck]
-            skp2 = map(lambda x: x + i + mm, skp2)
-            skp2 = filter(lambda x: x != 0, skp2)
-            lskp += [ SkewPartition([skp1, skp2]) ]
-        return lskp
-
-
-    def list(self):
-        """
-        Returns a list of all the skew partitions that have row lengths
-        given by the composition self.co.
-
-        EXAMPLES:
-            sage: SkewPartitions(row_lengths=[2,2]).list()
-            [[[2, 2], []], [[3, 2], [1]], [[4, 2], [2]]]
-            sage: SkewPartitions(row_lengths=[2,2], overlap=1).list()
-            [[[2, 2], []], [[3, 2], [1]]]
-        """
-        co = self.co
-        overlap = self.overlap
-
-        if co == []:
-            return [ SkewPartition([[],[]]) ]
-
-        nn = len(co) 
-        if nn == 1:
-            return [ SkewPartition([[co[0]],[]]) ]
-
-        result = []
-        for sskp in SkewPartitions(row_lengths=co[:-1], overlap=overlap):
-            result += self._from_row_lengths_aux(sskp, co[-2], co[-1], overlap)
-        return result
-
-
-
-
-
-
Index: age/combinat/skew_tableau.py
===================================================================
--- sage/combinat/skew_tableau.py	(revision 6439)
+++ 	(revision )
@@ -1,668 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.rings.arith import factorial
-from sage.rings.integer import Integer
-from sage.combinat.partition import Partition
-import sage.combinat.tableau
-from sage.combinat.skew_partition import SkewPartition
-import partition
-import misc
-import word
-from sage.misc.all import prod
-import exceptions
-import random
-import copy
-from combinat import CombinatorialObject, CombinatorialClass
-from sage.graphs.graph import DiGraph
-
-def SkewTableau(st):
-    """
-    Returns the skew tableau object corresponding to st.
-
-    EXAMPLES:
-        sage: st = SkewTableau([[None, 1],[2,3]]); st
-        [[None, 1], [2, 3]]
-        sage: st.inner_shape()
-        [1]
-        sage: st.outer_shape()
-        [2, 2]
-    """
-    for row in st:
-        if not isinstance(row, list):
-            raise TypeError, "each element of the skew tableau must be a list"
-        if row == []:
-            raise TypeError, "a skew tableau cannot have an empty list for a row"
-        
-    return SkewTableau_class(st)
-
-class SkewTableau_class(CombinatorialObject):
-    def __init__(self, t):
-        """
-        TESTS:
-            sage: st = SkewTableau([[None, 1],[2,3]])
-            sage: st == loads(dumps(st))
-            True
-        """
-        CombinatorialObject.__init__(self,t)
-
-    def pp(self):
-        """
-        Returns a pretty print string of the tableau.
-        EXAMPLES:
-            sage: t = SkewTableau([[None,2,3],[None,4],[5]])
-            sage: print t.pp()
-              .  2  3
-              .  4
-              5
-        """
-
-        def none_str(x):
-            if x == None:
-                return "  ."
-            else:
-                return "%3s"%str(x)
-            
-        new_rows = [ "".join(map(none_str , row)) for row in self]
-        return '\n'.join(new_rows)
-
-    def outer_shape(self):
-        """
-        Returns the outer shape of the tableau.
-
-        EXAMPLES:
-            sage: SkewTableau([[None,1,2],[None,3],[4]]).outer_shape()
-            [3, 2, 1]
-        """
-        
-        return Partition([len(row) for row in self])
-
-
-    def inner_shape(self):
-        """
-        Returns the inner shape of the tableau.
-
-        EXAMPLES:
-            sage: SkewTableau([[None,1,2],[None,3],[4]]).inner_shape()
-            [1, 1]
-        """
-        
-        return Partition(filter(lambda x: x != 0, [len(filter(lambda x: x==None, row)) for row in self]))
-    
-    def shape(self):
-        r"""
-        Returns the shape of a tableau t.
-
-        EXAMPLES:
-            sage: SkewTableau([[None,1,2],[None,3],[4]]).shape()
-            [[3, 2, 1], [1, 1]]
-        """
-
-        return SkewPartition([self.outer_shape(), self.inner_shape()])
-
-    
-    def outer_size(self):
-        """
-        Returns the size of the outer shape of the skew tableau.
-
-        EXAMPLES:
-            sage: SkewTableau([[None, 2, 4], [None, 3], [1]]).outer_size()
-            6
-            sage: SkewTableau([[None, 2], [1, 3]]).outer_size()
-            4
-
-        """
-        return self.outer_shape().size()
-
-
-    def inner_size(self):
-        """
-        Returns the size of the inner shape of the skew tableau.
-
-        EXAMPLES:
-            sage: SkewTableau([[None, 2, 4], [None, 3], [1]]).inner_size()
-            2
-            sage: SkewTableau([[None, 2], [1, 3]]).inner_size()
-            1
-   
-        """
-        return self.inner_shape().size()
-
-    def size(self):
-        """
-        Returns the number of boxes in the skew tableau.
-
-        EXAMPLES:
-            sage: SkewTableau([[None, 2, 4], [None, 3], [1]]).size()
-            4
-            sage: SkewTableau([[None, 2], [1, 3]]).size()
-            3
-
-        """
-        return sum([len(filter(lambda x: x != None,row)) for row in self])
-
-
-
-    def conjugate(self):
-        """
-        Returns the conjugate of the skew tableau.
-
-        EXAMPLES:
-            sage: SkewTableau([[None,1],[2,3]]).conjugate()
-            [[None, 2], [1, 3]]
-        """
-        conj_shape = self.outer_shape().conjugate()
-
-        conj = [[None]*row_length for row_length in conj_shape]
-
-        for i in range(len(conj)):
-            for j in range(len(conj[i])):
-                conj[i][j] = self[j][i]
-
-
-        return SkewTableau(conj)
-
-    def to_word_by_row(self):
-        """
-        Returns a word obtained from a row reading of the skew tableau.
-
-        EXAMPLES:
-            sage: SkewTableau([[None,1],[2,3]]).to_word_by_row()
-            [1, 2, 3]
-            sage: SkewTableau([[None, 2, 4], [None, 3], [1]]).to_word_by_row()
-            [2, 4, 3, 1]
-        """
-        word = []
-        for row in self:
-            word += filter(lambda x: x!= None, row)
-
-        return word
-
-
-    def to_word_by_column(self):
-        """
-        Returns the word obtained from a column reading of the skew tableau
-
-        EXAMPLES:
-            sage: SkewTableau([[None,1],[2,3]]).to_word_by_column()
-            [2, 1, 3]
-            sage: SkewTableau([[None, 2, 4], [None, 3], [1]]).to_word_by_column()
-            [1, 2, 3, 4]      
-
-        """
-        word = []
-        conj = self.conjugate()
-        for row in conj:
-            word += filter(lambda x: x!= None, row)
-
-        return word
-
-    def to_word(self):
-        """
-        An alias for SkewTableau.to_word_by_row().
-        """
-        return self.to_word_by_row()
-
-    def evaluation(self):
-        """
-        Returns the evaluation of the word from skew tableau.
-
-        EXAMPLES:
-            sage: SkewTableau([[1,2],[3,4]]).evaluation()
-            [1, 1, 1, 1]
-        """
-
-        return word.evaluation(self.to_word())
-
-    def is_standard(self):
-        """
-        Returns True if t is a standard skew tableau and False otherwise.
-
-        EXAMPLES:
-            sage: SkewTableau([[None, 2], [1, 3]]).is_standard()
-            True
-            sage: SkewTableau([[None, 2], [2, 4]]).is_standard()
-            False
-            sage: SkewTableau([[None, 3], [2, 4]]).is_standard()
-            False
-            sage: SkewTableau([[None, 2], [2, 4]]).is_standard()
-            False
-        """
-        t = self
-        #Check to make sure that it is filled with 1...size
-        w = self.to_word()
-        w.sort()
-        if w != range(1, self.size()+1):
-            return False
-
-
-
-        #Check to make sure it is increasing along the rows
-        for row in t:
-            for i in range(1, len(row)):
-                if row[i] != None and row[i] <= row[i-1]:
-                    return False
-
-
-        #Check to make sure it is increasing along the columns
-        conj = t.conjugate()
-        for row in conj:
-            for i in range(1, len(row)):
-                if row[i] != None and row[i] <= row[i-1]:
-                    return False    
-
-        return True
-
-    def to_tableau(self):
-        """
-        Returns a tableau with the same filling.  This only works if the
-        inner shape of the skew tableau has size zero.
-
-        EXAMPLES:
-            sage: SkewTableau([[1,2],[3,4]]).to_tableau()
-            [[1, 2], [3, 4]]
-
-        """
-
-        if self.inner_size() != 0:
-            raise ValueError, "the inner size of the skew tableau must be 0"
-        else:
-            return  sage.combinat.tableau.Tableau(self[:])
-
-    def restrict(self, n):
-        """
-        Returns the restriction of the standard skew tableau to all the numbers less
-        than or equal to n.
-
-        EXAMPLES:
-            sage: SkewTableau([[None,1],[2],[3]]).restrict(2)
-            [[None, 1], [2]]
-            sage: SkewTableau([[None,1],[2],[3]]).restrict(1)
-            [[None, 1]]            
-        """
-        t = self[:]
-        if not self.is_standard():
-            raise ValueError, "the skew tableau must be standard to perform the restriction"
-        
-        return SkewTableau( filter(lambda z: z != [], map(lambda x: filter(lambda y: y <= n, x), t)) )
-    
-    def to_chain(self):
-        """
-        Returns the chain of skew partitions corresponding to the standard
-        skew tableau.
-
-        EXAMPLES:
-            sage: SkewTableau([[None,1],[2],[3]]).to_chain()
-            [[[1], [1]], [[2], [1]], [[2, 1], [1]], [[2, 1, 1], [1]]]
-        """
-        if not self.is_standard():
-            raise ValueError, "the skew tableau must be standard to convert to a chain"
-
-        return map(lambda x: self.restrict(x).shape(), range(self.size()+1))
-
-    def slide(self, corner=None):
-        """
-
-        Fulton, William. 'Young Tableaux'. p12-13
-        
-        EXAMPLES:
-            sage: st = SkewTableau([[None, None, None, None,2],[None, None, None, None,6], [None, 2, 4, 4], [2, 3, 6], [5,5]])
-            sage: st.slide([2,0])
-            [[None, None, None, None, 2], [None, None, None, None, 6], [2, 2, 4, 4], [3, 5, 6], [5]]
-
-        """
-        new_st = copy.copy(self[:])
-        inner_corners = self.inner_shape().corners()
-        outer_corners = self.outer_shape().corners()
-        if corner != None:
-            if corner not in inner_corners:
-                raise ValueError, "corner must be an inner corner"
-        else:
-            if len(inner_corners) == 0:
-                return self
-            else:
-                corner = inner_corners[0]
-
-        spot = corner[:]
-        while spot not in outer_corners:
-            #print spot
-            #Check to see if there is nothing to the right
-            if spot[1] == len(new_st[spot[0]]) - 1:
-                #print "nr"
-                #Swap the hole with the box below
-                new_st[spot[0]][spot[1]] = new_st[spot[0]+1][spot[1]]
-                new_st[spot[0]+1][spot[1]] = None
-                spot[0] += 1
-                continue
-                
-            #Check to see if there is nothing below
-            if (spot[0] == len(new_st) - 1) or (len(new_st[spot[0]+1]) <= spot[1]):
-                #print "nb"
-                #Swap the hole with the box to the right
-                new_st[spot[0]][spot[1]] = new_st[spot[0]][spot[1]+1]
-                new_st[spot[0]][spot[1]+1] = None
-                spot[1] += 1
-                continue
-
-            #If we get to this stage, we need to compare
-            below = new_st[spot[0]+1][spot[1]]
-            right = new_st[spot[0]][spot[1]+1]
-            if below <= right:
-                #Swap with the box below
-                #print "b"
-                new_st[spot[0]][spot[1]] = new_st[spot[0]+1][spot[1]]
-                new_st[spot[0]+1][spot[1]] = None
-                spot[0] += 1
-                continue
-            else:
-                #Swap with the box to the right
-                #print "r"
-                new_st[spot[0]][spot[1]] = new_st[spot[0]][spot[1]+1]
-                new_st[spot[0]][spot[1]+1] = None
-                spot[1] += 1
-                continue
-            
-        #Clean up to remove the "None" at an outside corner
-        #Remove the last row if there is nothing left in it
-        new_st[spot[0]].pop()
-        if len(new_st[spot[0]]) == 0:
-            new_st.pop()
-        
-        return SkewTableau(new_st)
-                
-
-    def rectify(self):
-        """
-        Returns a Tableau formed by applying the jeu de taquin process to
-        self.
-
-        Fulton, William. 'Young Tableaux'. p15
-
-        EXAMPLES:
-        """
-        rect = copy.deepcopy(self)
-        inner_corners = rect.inner_shape().corners()
-
-        while len(inner_corners) > 0:
-            rect = rect.slide()
-            inner_corners = rect.inner_shape().corners()
-
-        return rect.to_tableau()
-
-
-
-        
-class SkewTableauWithContent(SkewTableau_class):
-    def _setmin(self, y, x, initial=None):
-        #Compute t which is the "minimum" skew tableau with
-        #the given content
-        #t = [ [0]*self.outer[i] for i in range(len(self.outer)) ]
-        if initial == None:
-            t = self.list
-        else:
-            t = initial
-
-        #this algorithm comes from st_setmin
-        #print "Call: (%d, %d)"%(y,x)
-        while ( y < self.rows ):
-            while x >= self.inner[y]:
-                if y == 0 or x < self.inner[y-1]:
-                    e = 0
-                else:
-                    e = t[y-1][x] + 1
-
-                t[y][x] = e
-                try:
-                    self.conts[e] += 1
-                except:
-                    raise IndexError, "(%d,%d): %d, %s"%(y,x, e, str(self.conts))
-
-                x -= 1
-            y += 1
-
-            if y < self.rows:
-                x = self.outer[y] - 1
-        return t
-
-    def __init__(self, outer, inner, conts=None, maxrows=0):
-        self.rows = len(outer)
-
-        if conts != None:
-            self.clen = len(conts)
-        else:
-            self.clen = 0
-        self.clen += self.rows
-      
-        self.conts = [0]*self.clen
-        if conts != None:
-            for i in range(len(conts)):
-                self.conts[i] = conts[i]
-
-        self.outer = outer[:]
-        self.inner = inner[:] + [0]*(len(outer)-len(inner))
-        
-        if len(self.outer) == 0:
-            self.cols = 0
-        else:
-            self.cols = self.outer[0]
-
-
-        initial = [ [0]*self.outer[i] for i in range(len(self.outer)) ]
-        t = self._setmin(0, self.outer[0]-1, initial=initial)
-        SkewTableau.__init__(self,t)
-
-        self.outer_conj = None
-        
-        self.maxrows = maxrows
-        if (maxrows >= self.clen):
-            self.maxrows = 0
-
-        if self.maxrows == 0:
-            return
-
-        if self.conts[self.maxrows] != 0:
-            raise ValueError, " self.conts[self.maxrows] != 0 "
-
-        self.outer_conj = Partition(self.outer).conjugate()
-
-    def next(self):
-        """
-        Returns the next semistandard skew tableau
-        """
-        #new_st = copy.copy(self)
-        #IMPLEMENTATION SPECIFIC
-        l = self.list
-
-        for y in reversed(range(self.rows)):
-            xlim = self.outer[y]
-
-            for x in range(self.inner[y], xlim):
-                if self.maxrows == 0:
-                    elim = len(self.conts) -1
-                else:
-                    elim = self.maxrows + y - self.outer_conj[x]
-
-                if x != xlim - 1:
-                    next_cell = l[y][x+1]
-                    if next_cell < elim:
-                        elim = next_cell
-
-                e = l[y][x]
-                self.conts[e] -= 1
-
-                e += 1
-                while ( e <= elim and
-                        self.conts[e] == self.conts[e-1] ):
-                    e += 1
-
-                if e <= elim:
-                    l[y][x] = e
-                    self.conts[e] += 1
-
-                    #IMPLEMENTATION SPECIFIC
-                    #new_st._setmin(y, x-1)
-                    self._setmin(y,x-1)
-                    return self
-                    #return new_st
-
-        return False
-                    
-                    
-def st_iterator(outer, inner, conts=None, maxrows=0):
-    st = SkewTableauWithContent(outer,inner,conts=conts,maxrows=maxrows)
-    yield st
-
-    next = st.next()
-    while next != False:
-        yield next
-        next = next.next()
-        
-
-
-def _label_skew(list, sk):
-    """
-    Returns a filled in a standard skew tableaux given an ordered list of the
-    coordinates to filled in.
-
-    EXAMPLES:
-        sage: l = [ '0,0', '1,1', '1,0', '0,1' ]
-        sage: empty = [[None,None],[None,None]]
-        sage: skew_tableau._label_skew(l, empty)
-        [[1, 4], [3, 2]]
-    """
-    i = 1
-    skew = copy.deepcopy(sk)
-    for coordstring in list:
-            coords = coordstring.split(",")
-            row = int(coords[0])
-            column = int(coords[1])
-            skew[row][column] = i
-            i += 1
-    return skew
-
-def StandardSkewTableaux(skp):
-    """
-    Returns the combinatorial class of standard skew tableaux of
-    shape skp (where skp is a skew partition).
-
-    EXAMPLES:
-        sage: StandardSkewTableaux([[3, 2, 1], [1, 1]]).list()
-        [[[None, 1, 2], [None, 3], [4]],
-         [[None, 1, 2], [None, 4], [3]],
-         [[None, 1, 3], [None, 2], [4]],
-         [[None, 1, 4], [None, 2], [3]],
-         [[None, 1, 3], [None, 4], [2]],
-         [[None, 1, 4], [None, 3], [2]],
-         [[None, 2, 3], [None, 4], [1]],
-         [[None, 2, 4], [None, 3], [1]]]
-    """
-    return StandardSkewTableaux_skewpartition(SkewPartition(skp))
-
-class StandardSkewTableaux_skewpartition(CombinatorialClass):
-    object_class = SkewTableau_class
-    def __init__(self, skp):
-        """
-        TESTS:
-            sage: S = StandardSkewTableaux([[3, 2, 1], [1, 1]])
-            sage: S == loads(dumps(S))
-            True
-        """
-        self.skp = skp
-
-    def list(self):
-        """
-        Returns a list for all the standard skew tableaux with shape
-        of the skew partition skp. The standard skew tableaux are
-        ordered lexicographically by the word obtained from their
-        row reading.
-
-        EXAMPLES:
-            sage: StandardSkewTableaux([[3, 2, 1], [1, 1]]).list()
-            [[[None, 1, 2], [None, 3], [4]],
-             [[None, 1, 2], [None, 4], [3]],
-             [[None, 1, 3], [None, 2], [4]],
-             [[None, 1, 4], [None, 2], [3]],
-             [[None, 1, 3], [None, 4], [2]],
-             [[None, 1, 4], [None, 3], [2]],
-             [[None, 2, 3], [None, 4], [1]],
-             [[None, 2, 4], [None, 3], [1]]]
-
-        """
-        return [st for st in self]
-
-    def count(self):
-        """
-        Returns the number of standard skew tableaux with shape of the
-        skew partition skp.
-
-        EXAMPLES:
-            sage: StandardSkewTableaux([[3, 2, 1], [1, 1]]).count()
-            8
-        """
-
-        return sum([1 for st in self])
-
-    def iterator(self):
-        """
-        An iterator for all the standard skew tableau with shape of the
-        skew partition skp. The standard skew tableaux are
-        ordered lexicographically by the word obtained from their
-        row reading.
-
-        EXAMPLES:
-            sage: [st for st in StandardSkewTableaux([[3, 2, 1], [1, 1]])]
-            [[[None, 1, 2], [None, 3], [4]],
-             [[None, 1, 2], [None, 4], [3]],
-             [[None, 1, 3], [None, 2], [4]],
-             [[None, 1, 4], [None, 2], [3]],
-             [[None, 1, 3], [None, 4], [2]],
-             [[None, 1, 4], [None, 3], [2]],
-             [[None, 2, 3], [None, 4], [1]],
-             [[None, 2, 4], [None, 3], [1]]]
-        """
-        skp = self.skp
-        
-        dag = skp.to_dag()
-        le_list = list(dag.topological_sort_generator())
-
-        empty = [[None]*row_length for row_length in skp.outer()]
-
-        for le in le_list:
-            yield SkewTableau(_label_skew(le, empty))
-
-    
-
-def from_shape_and_word(shape, word):
-    """
-    Returns the skew tableau correspnding to the skew partition
-    shape and the word obtained from the row reading.
-
-    EXAMPLES:
-        sage: t = SkewTableau([[None, 2, 4], [None, 3], [1]])
-        sage: shape = t.shape()
-        sage: word  = t.to_word() 
-        sage: skew_tableau.from_shape_and_word(shape, word)
-        [[None, 2, 4], [None, 3], [1]]
-
-    """
-    st = [ [None]*row_length for row_length in shape[0] ]
-    w_count = 0
-    for i in range(len(shape[0])):
-        for j in range(shape[0][i]):
-            if i >= len(shape[1]) or j >= shape[1][i]:
-                st[i][j] = word[w_count]
-                w_count += 1
-    return SkewTableau(st)
-    
Index: sage/combinat/sloane_functions.py
===================================================================
--- sage/combinat/sloane_functions.py	(revision 6439)
+++ sage/combinat/sloane_functions.py	(revision 6235)
@@ -101,5 +101,4 @@
 import sage.calculus.all as calculus
 from sage.functions.transcendental import prime_pi
-import partition
 
 Integer = ZZ
@@ -2662,5 +2661,5 @@
 
     def _eval(self, n):
-        return partition.Partitions(n).count()
+        return combinat.number_of_partitions(n)
 
 
Index: age/combinat/split_nk.py
===================================================================
--- sage/combinat/split_nk.py	(revision 6439)
+++ 	(revision )
@@ -1,118 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.rings.arith import binomial
-import random as rnd
-import sage.combinat.choose_nk as choose_nk
-from combinat import CombinatorialClass
-
-def SplitNK(n, k):
-    """
-    Returns the combinatorial class of splits of
-    a the set range(n) into a set of size k and a
-    set of size k.
-
-    EXAMPLES:
-        sage: S = sage.combinat.split_nk.SplitNK(5,2); S
-        Splits of {0, ..., 4} into a set of size 2 and one of size 3
-        sage: S.first()
-        [[0, 1], [2, 3, 4]]
-        sage: S.last()
-        [[3, 4], [0, 1, 2]]
-        sage: S.list()
-        [[[0, 1], [2, 3, 4]],
-         [[0, 2], [1, 3, 4]],
-         [[0, 3], [1, 2, 4]],
-         [[0, 4], [1, 2, 3]],
-         [[1, 2], [0, 3, 4]],
-         [[1, 3], [0, 2, 4]],
-         [[1, 4], [0, 2, 3]],
-         [[2, 3], [0, 1, 4]],
-         [[2, 4], [0, 1, 3]],
-         [[3, 4], [0, 1, 2]]]
-    """
-    return SplitNK_nk(n,k)
-
-class SplitNK_nk(CombinatorialClass):
-    def __init__(self, n, k):
-        """
-        TESTS:
-            sage: S = sage.combinat.split_nk.SplitNK(5,2)
-            sage: S == loads(dumps(S))
-            True
-        """
-        self.n = n
-        self.k = k
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(sage.combinat.split_nk.SplitNK(5,2))
-            'Splits of {0, ..., 4} into a set of size 2 and one of size 3'
-        """
-        return "Splits of {0, ..., %s} into a set of size %s and one of size %s"%(self.n-1, self.k, self.n-self.k)
-
-    def count(self):
-        """
-        Returns the number of choices of set partitions of
-        range(n) into a set of size k and a set of size
-        n-k.
-
-        EXAMPLES:
-            sage: sage.combinat.split_nk.SplitNK(5,2).count()
-            10
-        """
-        return binomial(self.n,self.k)
-
-    def iterator(self):
-        """
-        An iterator for all set partitions of
-        range(n) into a set of size k and a set of size
-        n-k in lexicographic order.
-
-        EXAMPLES:
-            sage: [c for c in sage.combinat.split_nk.SplitNK(5,2)]
-            [[[0, 1], [2, 3, 4]],
-             [[0, 2], [1, 3, 4]],
-             [[0, 3], [1, 2, 4]],
-             [[0, 4], [1, 2, 3]],
-             [[1, 2], [0, 3, 4]],
-             [[1, 3], [0, 2, 4]],
-             [[1, 4], [0, 2, 3]],
-             [[2, 3], [0, 1, 4]],
-             [[2, 4], [0, 1, 3]],
-             [[3, 4], [0, 1, 2]]]
-        """
-        range_n = range(self.n)
-        for kset in choose_nk.ChooseNK(self.n,self.k):
-            yield [ kset, filter(lambda x: x not in kset, range_n) ]
-
-
-    def random(self):
-        """
-        Returns a random set partition of
-        range(n) into a set of size k and a set of size
-        n-k.
-
-        EXAMPLES:
-            sage: sage.combinat.split_nk.SplitNK(5,2).random() #random
-            [[1, 3], [0, 2, 4]]
-        """
-        r = rnd.sample(xrange(self.n),self.n)
-        r0 = r[:self.k]
-        r1 = r[self.k:]
-        r0.sort()
-        r1.sort()
-        return [ r0, r1 ]
Index: age/combinat/subset.py
===================================================================
--- sage/combinat/subset.py	(revision 6439)
+++ 	(revision )
@@ -1,416 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.sets.set import Set
-from sage.rings.arith import binomial
-import sage.rings.integer
-import sage.combinat.subword as subword
-import sage.combinat.choose_nk as choose_nk
-import random as rnd
-import __builtin__
-import itertools
-from combinat import CombinatorialClass, CombinatorialObject
-
-
-
-def Subsets(s, k=None):
-    """
-    Returns the combinatorial class of subsets of s.
-
-    If s is a non-negative integer, it returns the subsets of
-    range(1,s+1).
-
-    If k is specified, it returns the subsets of s of size
-    k.
-
-    EXAMPLES:
-        sage: S = Subsets([1,2,3]); S
-        Subsets of {1, 2, 3}
-        sage: S.count()
-        8
-        sage: S.first()
-        {}
-        sage: S.last()
-        {1, 2, 3}
-        sage: S.random() #random
-        {2, 3}
-        sage: S.list()
-        [{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}]
-
-        sage: S = Subsets(3)
-        sage: S.list()
-        [{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}]
-
-        sage: S = Subsets(3,2); S
-        Subsets of {1, 2, 3} of size 2
-        sage: S.list()
-        [{1, 2}, {1, 3}, {2, 3}]
-
-    """
-    if isinstance(s, (int, sage.rings.integer.Integer)):
-        if s < 0:
-            raise ValueError, "s must be non-negative"
-        set = Set(range(1,s+1))
-    else:
-        set = Set(s)
-    
-    if k == None:
-        return Subsets_s(set)
-    else:
-        if isinstance(k, (int, sage.rings.integer.Integer)):
-            return Subsets_sk(set, k)
-        else:
-            raise TypeError, "k must be an integer"
-
-
-
-
-class Subsets_s(CombinatorialClass):
-    def __init__(self, s):
-        """
-        TESTS:
-            sage: S = Subsets([1,2,3])
-            sage: S == loads(dumps(S))
-            True
-        """
-        self.s = s
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Subsets([1,2,3]))
-            'Subsets of {1, 2, 3}'
-        """
-        return "Subsets of %s"%self.s
-
-    def count(self):
-        r"""
-        Returns the number of subsets of the set s.
-
-        This is given by $2^{|s|}$.
-        
-        EXAMPLES:
-            sage: Subsets(Set([1,2,3])).count()
-            8
-            sage: Subsets([1,2,3,3]).count()
-            8
-            sage: Subsets(3).count()
-            8
-        """
-        return 2**len(self.s)
-
-    def first(self):
-        """
-        Returns the first subset of s.  Since we aren't restricted
-        to subsets of a certain size, this is always the empty
-        set.
-
-        EXAMPLES:
-            sage: Subsets([1,2,3]).first()
-            {}
-            sage: Subsets(3).first()
-            {}
-        """
-        return Set([])
-
-    def last(self):
-        """
-        Returns the last subset of s.  Since we aren't restricted
-        to subsets of a certain size, this is always the set s
-        itself.
-
-        EXAMPLES:
-            sage: Subsets([1,2,3]).last()
-            {1, 2, 3}
-            sage: Subsets(3).last()
-            {1, 2, 3}
-        """
-        return self.s
-
-    
-    def iterator(self):
-        """
-        An iterator for all the subsets of s.
-
-        EXAMPLES:
-            sage: [sub for sub in Subsets(Set([1,2,3]))]
-            [{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}]
-            sage: [sub for sub in Subsets([1,2,3,3])]
-            [{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}]
-            sage: [sub for sub in Subsets(3)]
-            [{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}]
-        """
-        lset = __builtin__.list(self.s)
-        #We use the iterator for the subwords of range(len(self.s))
-        ind_set = lambda index_list: Set([lset[i] for i in index_list])
-        it = itertools.imap(ind_set, subword.Subwords(range(len(lset))))
-        for sub in it:
-            yield sub
-
-    def random(self):
-        """
-        Returns a random subset of s.
-
-        EXAMPLES:
-            sage: Subsets(3).random() #random
-            {1}
-            sage: Subsets([4,5,6]).random() #random
-            {4, 5, 6}
-        """
-        lset = __builtin__.list(self.s)
-        n = len(self.s)
-        return Set(filter(lambda x: rnd.randint(0,1), lset))
-
-    def rank(self, sub):
-        """
-        Returns the rank of sub as a subset of s.
-
-        EXAMPLES:
-            sage: Subsets(3).rank([])
-            0
-            sage: Subsets(3).rank([1,2])
-            4
-            sage: Subsets(3).rank([1,2,3])
-            7
-            sage: Subsets(3).rank([2,3,4]) == None
-            True
-        """
-        subset = Set(sub)
-        lset = __builtin__.list(self.s)
-        lsubset = __builtin__.list(subset)
-
-        try:
-            index_list = map(lambda x: lset.index(x), lsubset)
-            index_list.sort()
-        except ValueError:
-            return None
-
-        n = len(self.s)
-        r = 0
-
-        for i in range(len(index_list)):
-            r += binomial(n,i)
-        return r + choose_nk.rank(index_list,n)
-
-    def unrank(self, r):
-        """
-        Returns the subset of s that has rank k.
-
-        EXAMPLES:
-            sage: Subsets(3).unrank(0)
-            {}
-            sage: Subsets([2,4,5]).unrank(1)
-            {2}
-            sage: s = Subsets([2,4,5])
-        """
-
-        lset = __builtin__.list(self.s)
-        n = len(lset)
-
-        if r >= self.count() or r < 0:
-            return None
-        else:
-            for k in range(n+1):
-                bin = binomial(n,k)
-                if r >= bin:
-                    r = r - bin
-                else:
-                    return Set([lset[i] for i in choose_nk.from_rank(r, n, k)])
-
-
-class Subsets_sk(CombinatorialClass):
-    def __init__(self, s, k):
-        """
-        TESTS:
-            sage: S = Subsets(3,2)
-            sage: S == loads(dumps(S))
-            True
-        """
-        self.s = s
-        self.k = k
-
-    def __repr__(self):
-        """
-        TESTS:
-           sage: repr(Subsets(3,2))
-           'Subsets of {1, 2, 3} of size 2'
-        """
-        return "Subsets of %s of size %s"%(self.s, self.k)
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: Subsets([1,2,3,3], 2).count()
-            3
-            sage: Subsets(Set([1,2,3]), 2).count()
-            3
-            sage: Subsets([1,2,3], 1).count()
-            3
-            sage: Subsets([1,2,3], 3).count()
-            1
-            sage: Subsets([1,2,3], 0).count()
-            1
-            sage: Subsets([1,2,3], 4).count()
-            0
-            sage: Subsets(3,2).count()
-            3
-            sage: Subsets(3,4).count()
-            0
-        """
-        if self.k not in range(len(self.s)+1):
-            return 0
-        else:
-            return binomial(len(self.s),self.k)
-
-        
-    def first(self):
-        """
-        Returns the first subset of s of size k.
-
-        EXAMPLES:
-            sage: Subsets(Set([1,2,3]), 2).first()
-            {1, 2}
-            sage: Subsets([1,2,3,3], 2).first()
-            {1, 2}
-            sage: Subsets(3,2).first()
-            {1, 2}
-            sage: Subsets(3,4).first()
-
-        """
-        if self.k not in range(len(self.s)+1):
-            return None
-        else:
-            return Set(__builtin__.list(self.s)[:self.k])
-
-
-
-    def last(self):
-        """
-        Returns the last subset of s of size k.
-
-        EXAMPLES:
-            sage: Subsets(Set([1,2,3]), 2).last()
-            {2, 3}
-            sage: Subsets([1,2,3,3], 2).last()
-            {2, 3}
-            sage: Subsets(3,2).last()
-            {2, 3}
-            sage: Subsets(3,4).last()
-        """
-        if self.k not in range(len(self.s)+1):
-            return None
-        else:
-            return Set(__builtin__.list(self.s)[-self.k:])
-
-
-
-
-    def iterator(self):
-        """
-        An iterator for all the subsets of s of size k.
-
-        EXAMPLES:
-            sage: [sub for sub in Subsets(Set([1,2,3]), 2)]
-            [{1, 2}, {1, 3}, {2, 3}]
-            sage: [sub for sub in Subsets([1,2,3,3], 2)]
-            [{1, 2}, {1, 3}, {2, 3}]
-            sage: [sub for sub in Subsets(3,2)]
-            [{1, 2}, {1, 3}, {2, 3}]        
-        """
-        if self.k not in range(len(self.s)+1):
-            return
-        
-        lset = __builtin__.list(self.s)
-        #We use the iterator for the subwords of range(len(self.s))
-        ind_set = lambda index_list: Set([lset[i] for i in index_list])
-        it = itertools.imap(ind_set, subword.Subwords(range(len(lset)),self.k))
-        for sub in it:
-            yield sub
-    
-
-
-    def random(self):
-        """
-        Returns a random subset of s of size k.
-
-        EXAMPLES:
-            sage: Subsets(3, 2).random() #random
-            {1, 2}
-            sage: Subsets(3,4).random()
-            None
-        """
-        lset = __builtin__.list(self.s)
-        n = len(self.s)
-
-        if self.k not in range(len(self.s)+1):
-            return None
-        else:
-            return Set([lset[i] for i in choose_nk.ChooseNK(n, self.k).random()])
-
-    def rank(self, sub):
-        """
-        Returns the rank of sub as a subset of s of size k.
-
-        EXAMPLES:
-            sage: Subsets(3,2).rank([1,2])
-            0
-            sage: Subsets([2,3,4],2).rank([3,4])
-            2
-            sage: Subsets([2,3,4],2).rank([2])
-            sage: Subsets([2,3,4],4).rank([2,3,4,5])       
-        """
-        subset = Set(sub)
-        lset = __builtin__.list(self.s)
-        lsubset = __builtin__.list(subset)
-
-        try:
-            index_list = map(lambda x: lset.index(x), lsubset)
-            index_list.sort()
-        except ValueError:
-            return None
-
-        n = len(self.s)
-        r = 0
-
-        if self.k not in range(len(self.s)+1):
-            return None
-        elif self.k != len(subset):
-            return None
-        else:
-            return choose_nk.rank(index_list,n)
-
-
-    def unrank(self, r):
-        """
-        Returns the subset of s that has rank k.
-
-        EXAMPLES:
-            sage: Subsets(3,2).unrank(0)
-            {1, 2}
-            sage: Subsets([2,4,5],2).unrank(0)
-            {2, 4}
-        """
-
-        lset = __builtin__.list(self.s)
-        n = len(lset)
-
-        if self.k not in range(len(self.s)+1):
-            return None
-        elif r >= self.count() or r < 0:
-            return None
-        else:
-            return Set([lset[i] for i in choose_nk.from_rank(r, n, self.k)])            
-
-
Index: age/combinat/subword.py
===================================================================
--- sage/combinat/subword.py	(revision 6439)
+++ 	(revision )
@@ -1,229 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 sage.combinat.combination as combination
-from sage.rings.arith import factorial
-import itertools
-from combinat import CombinatorialClass, CombinatorialObject
-
-#A subword of a word w is a word obtaining by deleting the letters at
-#some of the positions in w.
-
-#Example:
-#    - [b,n,j,r] is a subword of [b,o,n,j,o,u,r]
-#    - [n,r] is a subword of [b,o,n,j,o,u,r]
-#    - [r,n] is not a subword of [b,o,n,j,o,u,r]
-#    - [n,n,u] is not a subword of [b,o,n,j,o,u,r]
-#    - [n,n,u] is a subword with repetitions of [b,o,n,j,o,u,r]
-
-
-def Subwords(w, k=None):
-    """
-    Returns the combinatorial class of subwords of w.
-
-    If k is specified, then it returns the combinatorial class
-    of subwords of w of length k.
-
-    EXAMPLES:
-        sage: S = Subwords(['a','b','c']); S
-        Subwords of ['a', 'b', 'c']
-        sage: S.first()
-        []
-        sage: S.last()
-        ['a', 'b', 'c']
-        sage: S.list()
-        [[], ['a'], ['b'], ['c'], ['a', 'b'], ['a', 'c'], ['b', 'c'], ['a', 'b', 'c']]
-
-        sage: S = Subwords(['a','b','c'], 2); S
-        Subwords of ['a', 'b', 'c'] of length 2
-        sage: S.list()
-        [['a', 'b'], ['a', 'c'], ['b', 'c']]
-
-    """
-    if k == None:
-        return Subwords_w(w)
-    else:
-        if k not in range(0, len(w)+1):
-            raise ValueError, "k must be between 0 and %s"%len(w)
-        else:
-            return Subwords_wk(w,k)
-
-
-class Subwords_w(CombinatorialClass):
-    def __init__(self, w):
-        """
-        TESTS:
-            sage: S = Subwords([1,2,3])
-            sage: S == loads(dumps(S))
-            True
-        """
-        self.w = w
-        
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Subwords([1,2,3]))
-            'Subwords of [1, 2, 3]'
-        """
-        return "Subwords of %s"%self.w
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: Subwords([1,2,3]).count()
-            8
-        """
-        return 2**len(self.w)
-
-    def first(self):
-        """
-        EXAMPLES:
-            sage: Subwords([1,2,3]).first()
-            []
-        """
-        return []
-
-    def last(self):
-        """
-        EXAMPLES:
-            sage: Subwords([1,2,3]).last()
-            [1, 2, 3]
-        """
-        return self.w
-
-    def iterator(self):
-        r"""
-        EXAMPLES:
-            sage: [sw for sw in Subwords([1,2,3])]
-            [[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
-        """
-        #Case 1: recursively build a generator for all the subwords
-        #        length k and concatenate them together
-        w = self.w
-        return itertools.chain(*[Subwords_wk(w,i) for i in range(0,len(w)+1)])
-
-
-class Subwords_wk(CombinatorialClass):
-    def __init__(self, w, k):
-        """
-        TESTS:
-            sage: S = Subwords([1,2,3],2)
-            sage: S == loads(dumps(S))
-            True
-        """
-        self.w = w
-        self.k = k
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Subwords([1,2,3],2))
-            'Subwords of [1, 2, 3] of length 2'
-        """
-        return "Subwords of %s of length %s"%(self.w, self.k)
-
-    
-    def count(self):
-        r"""
-        Returns the number of subwords of w of length k.
-        
-        EXAMPLES:
-            sage: Subwords([1,2,3], 2).count()
-            3
-        """
-        w = self.w
-        k = self.k
-        return factorial(len(w))/(factorial(k)*factorial(len(w)-k))
-
-
-    def first(self):
-        r"""
-
-        EXAMPLES:
-            sage: Subwords([1,2,3],2).first()
-            [1, 2]
-            sage: Subwords([1,2,3],0).first()
-            []
-        """
-        return self.w[:self.k]
-
-    def last(self):
-        r"""
-        EXAMPLES:
-            sage: Subwords([1,2,3],2).last()
-            [2, 3]
-        """
-
-        return self.w[-self.k:]
-
-
-
-    def iterator(self):
-        """
-        EXAMPLES:
-            sage: [sw for sw in Subwords([1,2,3],2)]
-            [[1, 2], [1, 3], [2, 3]]
-            sage: [sw for sw in Subwords([1,2,3],0)]
-            [[]]
-        """
-        w = self.w
-        k = self.k
-        #Case 1: k == 0
-        if k == 0:
-            return itertools.repeat([],1)
-
-        #Case 2: build a generator for the subwords of length k
-        gen = combination.Combinations(range(len(w)), k).iterator()
-        return itertools.imap(lambda subword: [w[x] for x in subword], gen)
-    
-
-def smallest_positions(word, subword, pos = 0):
-    """
-    Returns the smallest positions for which subword apppears
-    as a subword of word.  If pos is specified, then it returns
-    the positions of the first appearance of subword starting
-    at pos.
-
-    If subword is not found in word, then it returns False
-
-    EXAMPLES:
-        sage: sage.combinat.subword.smallest_positions([1,2,3,4], [2,4])
-        [1, 3]
-        sage: sage.combinat.subword.smallest_positions([1,2,3,4,4], [2,4])
-        [1, 3]
-        sage: sage.combinat.subword.smallest_positions([1,2,3,3,4,4], [3,4])
-        [2, 4]
-        sage: sage.combinat.subword.smallest_positions([1,2,3,3,4,4], [3,4],2)
-        [2, 4]
-        sage: sage.combinat.subword.smallest_positions([1,2,3,3,4,4], [3,4],3)
-        [3, 4]
-        sage: sage.combinat.subword.smallest_positions([1,2,3,4], [2,3])
-        [1, 2]
-        sage: sage.combinat.subword.smallest_positions([1,2,3,4], [5,5])
-        False
-
-    """
-    pos -= 1
-    for i in range(len(subword)):
-        for j in range(pos+1, len(word)):
-            if word[j] == subword[i]:
-                pos = j
-                break
-        if pos == -1:
-            return False
-        subword[i] = pos
-
-    return subword
-    
Index: age/combinat/symmetric_group_algebra.py
===================================================================
--- sage/combinat/symmetric_group_algebra.py	(revision 6439)
+++ 	(revision )
@@ -1,63 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 combinatorial_algebra import CombinatorialAlgebra
-import permutation
-
-def SymmetricGroupAlgebra(R,n):
-    """
-    Returns the symmetric group algebra of order n over R.
-
-    EXAMPLES:
-        sage: QS3 = SymmetricGroupAlgebra(QQ, 3); QS3
-        Symmetric group algebra of order 3 over Rational Field
-        sage: QS3(1)
-        [1, 2, 3]
-        sage: QS3(2)
-        2*[1, 2, 3]
-        sage: basis = [QS3(p) for p in Permutations(3)]
-        sage: a = sum(basis); a
-        [3, 1, 2] + [1, 2, 3] + [2, 3, 1] + [2, 1, 3] + [3, 2, 1] + [1, 3, 2]
-        sage: a^2
-        6*[3, 1, 2] + 6*[1, 2, 3] + 6*[2, 3, 1] + 6*[2, 1, 3] + 6*[3, 2, 1] + 6*[1, 3, 2]
-        sage: a^2 == 6*a
-        True
-        sage: b = QS3([3, 1, 2])
-        sage: b
-        [3, 1, 2]
-        sage: b*a
-        [3, 1, 2] + [1, 2, 3] + [2, 3, 1] + [2, 1, 3] + [3, 2, 1] + [1, 3, 2]
-        sage: b*a == a
-        True
-    """
-    return SymmetricGroupAlgebra_n(R,n)
-
-class SymmetricGroupAlgebra_n(CombinatorialAlgebra):
-    def __init__(self, R, n):
-        """
-        TESTS:
-            #sage: QS3 = SymmetricGroupAlgebra(QQ, 3)
-            #sage: QS3 == loads(dumps(QS3))
-            #True
-        """
-        self.n = n
-        self._combinatorial_class = permutation.Permutations(n)
-        self._name = "Symmetric group algebra of order %s"%self.n
-        self._one = permutation.Permutation(range(1,n+1))
-        self._prefix = ""
-        CombinatorialAlgebra.__init__(self, R)
-        
-    def _multiply_basis(self, left, right):
-        return left * right
Index: age/combinat/tableau.py
===================================================================
--- sage/combinat/tableau.py	(revision 6439)
+++ 	(revision )
@@ -1,1613 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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.rings.arith import factorial
-from sage.rings.integer import Integer
-import sage.combinat.skew_tableau
-from partition import Partition, Partitions
-from composition import Compositions
-import word
-import misc
-import partition
-import sage.libs.symmetrica.all as symmetrica
-from sage.misc.all import prod
-import exceptions
-import random
-import copy
-from sage.groups.perm_gps.permgroup import PermutationGroup
-from combinat import CombinatorialClass, CombinatorialObject
-import __builtin__
-
-def Tableau(t):
-    """
-    Returns the tableau object corresponding to t.
-
-    EXAMPLES:
-        sage: t = Tableau([[1,2,3],[4,5]]); t
-        [[1, 2, 3], [4, 5]]
-        sage: t.shape()
-        [3, 2]
-        sage: t.is_standard()
-        True
-    """
-    if t in Tableaux():
-        return Tableau_class(t)
-    raise ValueError, "invalid tableau"
-
-class Tableau_class(CombinatorialObject):
-    def __init__(self, t):
-        """
-        TESTS:
-            sage: t = Tableau([[1,2],[3,4]])
-            sage: t == loads(dumps(t))
-            True
-        """
-        for row in t:
-            if not isinstance(row, list):
-                raise TypeError, "each element of the tableau must be a list"
-            if row == []:
-                raise TypeError, "a tableau cannot have an empty list for a row"
-
-        CombinatorialObject.__init__(self,t)
-
-    def __div__(self, t):
-        """
-        Returns the skew partition self/t.
-
-        EXAMPLES:
-            sage: t = Tableau([[1,2,3],[3,4],[5]])
-            sage: t/[1,1]
-            [[None, 2, 3], [None, 4], [5]]
-            sage: t/[3,1]
-            [[None, None, None], [None, 4], [5]]
-        """
-
-        #if t is a list, convert to to a partition first
-        if isinstance(t, list):
-            t = Partition(t)
-
-        #Check to make sure that
-        if not self.shape().dominates(t):
-            raise ValueError, "the partition must dominate t"
-
-
-        st = copy.deepcopy(self.list)
-
-        for i in range(len(t)):
-            for j in range(t[i]):
-                st[i][j] = None
-
-        return sage.combinat.skew_tableau.SkewTableau(st)
-
-        
-
-    def shape(self):
-        r"""
-        Returns the shape of a tableau t.
-
-        EXAMPLES:
-            sage: Tableau([[1,2,3],[4,5],[6]]).shape()
-            [3, 2, 1]
-        """
-
-        return Partition([len(row) for row in self])
-    
-    def size(self):
-        """
-        Returns the size of the shape of the tableau t.
-
-        EXAMPLES:
-            sage: Tableau([[1, 4, 6], [2, 5], [3]]).size()
-            6
-            sage: Tableau([[1, 3], [2, 4]]).size()
-            4
-
-        """
-        return sum([len(row) for row in self])
-
-    def corners(self):
-        """
-        Returns the corners of the tableau t.
-
-        EXAMPLES:
-            sage: Tableau([[1, 4, 6], [2, 5], [3]]).corners()
-            [[0, 2], [1, 1], [2, 0]]
-            sage: Tableau([[1, 3], [2, 4]]).corners()
-            [[1, 1]]
-
-        """
-        return self.shape().corners()
-
-    def conjugate(self):
-        """
-        Returns the conjugate of the tableau t.
-
-        EXAMPLES:
-            sage: Tableau([[1,2],[3,4]]).conjugate()
-            [[1, 3], [2, 4]]
-        """
-        conj_shape = self.shape().conjugate()
-
-        conj = [[None]*row_length for row_length in conj_shape]
-
-        for i in range(len(conj)):
-            for j in range(len(conj[i])):
-                conj[i][j] = self[j][i]
-
-
-        return Tableau(conj)
-
-    def pp(self):
-        """
-        Returns a pretty print string of the tableau.
-        EXAMPLES:
-            sage: t = Tableau([[1,2,3],[3,4],[5]])
-            sage: print t.pp()
-              1  2  3
-              3  4
-              5
-        """
-        return '\n'.join([ "".join(map(lambda x: "%3s"%str(x) , row))  for row in self])
-
-    def to_word_by_row(self):
-        """
-        Returns a word obtained from a row reading of the tableau t.
-
-        EXAMPLES:
-            sage: Tableau([[1,2],[3,4]]).to_word_by_row()
-            [1, 2, 3, 4]
-            sage: Tableau([[1, 4, 6], [2, 5], [3]]).to_word_by_row()
-            [1, 4, 6, 2, 5, 3]
-        """
-        word = []
-        for row in self:
-            word += row
-
-        return word
-
-
-    def to_word_by_column(self):
-        """
-        Returns the word obtained from a column reading of the tableau t.
-
-        EXAMPLES:
-            sage: Tableau([[1,2],[3,4]]).to_word_by_column()
-            [1, 3, 2, 4]
-            sage: Tableau([[1, 4, 6], [2, 5], [3]]).to_word_by_column()
-            [1, 2, 3, 4, 5, 6]    
-        """
-        word = []
-        conj = self.conjugate()
-        for row in conj:
-            word += row
-
-        return word
-
-    def to_word(self):
-        """
-        An alias for to_word_by_row.
-        
-        EXAMPLES:
-            sage: Tableau([[1,2],[3,4]]).to_word()
-            [1, 2, 3, 4]
-            sage: Tableau([[1, 4, 6], [2, 5], [3]]).to_word()
-            [1, 4, 6, 2, 5, 3]
-        """
-        return self.to_word_by_row()
-
-    def evaluation(self):
-        """
-        Returns the evaluation of the word from tableau t.
-
-        EXAMPLES:
-            sage: Tableau([[1,2],[3,4]]).evaluation()
-            [1, 1, 1, 1]
-        """
-
-        return word.evaluation(self.to_word())
-
-    def is_standard(self):
-        """
-        Returns True if t is a standard tableau and False otherwise.
-
-        EXAMPLES:
-            sage: Tableau([[1, 3], [2, 4]]).is_standard()
-            True
-            sage: Tableau([[1, 2], [2, 4]]).is_standard()
-            False
-            sage: Tableau([[2, 3], [2, 4]]).is_standard()
-            False
-            sage: Tableau([[5, 3], [2, 4]]).is_standard()
-            False
-        """
-        t = self
-        #Check to make sure the first position is 1
-        fillings = []
-        for row in t:
-            fillings += row
-        fillings.sort()
-        if fillings != range(1, t.size()+1):
-            return False
-
-
-
-        #Check to make sure it is increasing along the rows
-        for row in t:
-            for i in range(1, len(row)):
-                if row[i] <= row[i-1]:
-                    return False
-
-
-        #Check to make sure it is increasing along the columns
-        conj = t.conjugate()
-        for row in conj:
-            for i in range(1, len(row)):
-                if row[i] <= row[i-1]:
-                    return False    
-
-        return True
-
-    def is_rectangular(self):
-        """
-        Returns True if the tableau t is rectangular and False otherwise.
-
-        EXAMPLES:
-            sage: Tableau([[1,2],[3,4]]).is_rectangular()
-            True
-            sage: Tableau([[1,2,3],[4,5],[6]]).is_rectangular()
-            False
-        """
-        width = len(self[0])
-        for row in self:
-            if len(row) != width:
-                return False
-        return True
-
-    def vertical_flip(self):
-        """
-        Returns the tableau obtained by vertically flipping the tableau t.
-        This only works for rectangular tableau.
-
-        EXAMPLES:
-            sage: Tableau([[1,2],[3,4]]).vertical_flip()
-            [[3, 4], [1, 2]]
-        """
-
-        if not self.is_rectangular():
-            raise TypeError, "the tableau must be rectangular to use verticl_flip()"
-
-        return Tableau([row for row in reversed(self)])
-
-    def rotate_180(self):
-        """
-        Returns the tableau obtained by rotating t by 180 degrees.
-
-        EXAMPLES:
-            sage: Tableau([[1,2],[3,4]]).rotate_180()
-            [[4, 3], [2, 1]]
-        """
-        if not self.is_rectangular():
-            raise TypeError, "the tableau must be rectangular to use verticl_flip()"
-
-        return Tableau([ [l for l in reversed(row)] for row in reversed(self) ])
-
-
-    def k_weight(self, k):
-        """
-        Returns the k-weight of the tableau t.
-
-        The i-th entry of the list is the number of different
-        diagonals in which lie boxes labelled by i.
-
-        EXAMPLES:
-
-        """
-        t = self
-        res = []
-        e = t.evaluation()
-
-        s = []
-        for i in range(len(t)):
-            s += [ [i,j] for j in range(len(t[-i])) ]
-
-        for l in range(1,len(e)+1):
-            new_s = filter(lambda x: t[len(t)-1-x[0]][x[1]] == l, s)
-
-            #If there are no elements that mee the condition
-            if new_s == [[]]:
-                res += [0]
-                continue
-
-            x = filter(lambda x: (x[0]-x[1])% k+1, new_s)
-
-            #Remove duplicates from x
-            u = {}
-            for element in x:
-                u[str(element)] = 1
-
-            res += [len(u.keys())]
-
-        return res
-
-
-    def restrict(self, n):
-        """
-        Returns the restriction of the standard tableau to n.
-
-        EXAMPLES:
-            sage: Tableau([[1,2],[3],[4]]).restrict(3)
-            [[1, 2], [3]]
-            sage: Tableau([[1,2],[3],[4]]).restrict(2)
-            [[1, 2]]            
-        """
-        t = self[:]
-        if not self.is_standard():
-            raise ValueError, "the tableau must be standard to perform the restriction"
-
-        return Tableau( filter(lambda z: z != [], map(lambda x: filter(lambda y: y <= n, x), t)) )
-
-    def to_chain(self):
-        """
-        Returns the chain of partitions corresponding to the standard
-        skew tableau.
-
-        EXAMPLES:
-            sage: Tableau([[1,2],[3],[4]]).to_chain()
-            [[], [1], [2], [2, 1], [2, 1, 1]]
-        """
-        if not self.is_standard():
-            raise ValueError, "the tableau must be standard to convert to a chain"
-
-        return map(lambda x: self.restrict(x).shape(), range(self.size()+1))
-  
-
-    def anti_restrict(self, n):
-        """
-        Returns the skew tableau formed by removing all of the boxes
-        from self that are filled with a number less than 
-
-        EXAMPLES:
-            sage: t = Tableau([[1,2,3],[4,5]]); t
-            [[1, 2, 3], [4, 5]]
-            sage: t.anti_restrict(1)
-            [[None, 2, 3], [4, 5]]
-            sage: t.anti_restrict(2)
-            [[None, None, 3], [4, 5]]
-            sage: t.anti_restrict(3)
-            [[None, None, None], [4, 5]]
-            sage: t.anti_restrict(4)
-            [[None, None, None], [None, 5]]
-
-        """
-        t = list(copy.deepcopy(self))
-
-        for row in xrange(len(t)):
-            for col in xrange(len(t[row])):
-                if t[row][col] <= n:
-                    t[row][col] = None
-        return sage.combinat.skew_tableau.SkewTableau( t )
-
-
-    def up(self):
-        """
-        An iterator for all the tableaux that can be obtained from self by adding a box.
-        EXAMPLES:
-            sage: t = Tableau([[1,2]])
-            sage: [x for x in t.up()]
-            [[[1, 2, 3]], [[1, 2], [3]]]
-        """
-        #Get a list of all places where we can add a box
-        #to the shape of self
-        
-        outside_corners = self.shape().outside_corners()
-
-        n = self.size()
-
-        #Go through and add n+1 to the end of each 
-        #of the rows 
-        for (row, col) in outside_corners:
-            new_t = map(list, self)
-            if row != len(self):
-                new_t[row] += [n+1]
-            else:
-                new_t.append([n+1])
-            yield Tableau(new_t)
-
-    def up_list(self):
-        """
-        Returns a list of all the tableaux that can be obtained from self by adding a box.
-        
-        EXAMPLES:
-            sage: t = Tableau([[1,2]]) 
-            sage: t.up_list() 
-            [[[1, 2, 3]], [[1, 2], [3]]]        
-        """
-        return list(self.up())
-
-    def down(self):
-        """
-        An iterator for all the tableaux that can be obtained from self by removing a box.  Note that this iterates just over a single tableaux.
-        EXAMPLES:
-            sage: t = Tableau([[1,2],[3]]) 
-            sage: [x for x in t.down()] 
-            [[[1, 2]]] 
-        """
-        yield self.restrict( self.size() - 1 )
-
-    def down_list(self):
-        """
-        Returns a list of all the tableaux that can be obtained from self by removing a box.  Note that this is just a single tableaux.
-        
-        EXAMPLES: 
-            sage: t = Tableau([[1,2],[3]])  
-            sage: t.down_list() 
-            [[[1, 2]]]
-        """
-        return list(self.down())
-
-
-    def bump(self, x):
-        """
-        Schensted's row-bumping (or row-insertion) algorithm.
-
-        EXAMPLES:
-            sage: t = Tableau([[1,2],[3]])
-            sage: t.bump(1)
-            [[1, 1], [2], [3]]
-            sage: t
-            [[1, 2], [3]]
-            sage: t.bump(2)
-            [[1, 2, 2], [3]]
-            sage: t.bump(3)
-            [[1, 2, 3], [3]]
-            sage: t
-            [[1, 2], [3]]
-            sage: t = Tableau([[1,2,2,3],[2,3,5,5],[4,4,6],[5,6]])
-            sage: t.bump(2)
-            [[1, 2, 2, 2], [2, 3, 3, 5], [4, 4, 5], [5, 6, 6]]
-
-        """
-        new_t = copy.deepcopy(self[:])
-        to_insert = x
-        row = 0
-        done = False
-        while not done:
-            #if we are at the end of the tableau
-            #add to_insert as the last row
-            if row == len(new_t):
-                new_t.append([to_insert])
-                break
-            
-            i = 0
-            #try to insert to_insert into row
-            while i < len(new_t[row]):                                                                                               
-                if to_insert < new_t[row][i]:
-                    t = to_insert
-                    to_insert = new_t[row][i]
-                    new_t[row][i] = t
-                    break
-                i += 1
-
-
-            #if we haven't already inserted to_insert
-            #append it to the end of row
-            if i == len(new_t[row]):
-                new_t[row].append(to_insert)
-                done = True
-
-            row += 1
-
-        return Tableau(new_t)
-                    
-    def bump_multiply(left, right):
-        """
-        Multiply two tableaux using Schensted's bump.
-
-        This product makes the set of tableaux into an associative monoid.
-        The empty tableaux is the unit in this monoid.
-
-        Fulton, William. 'Young Tableaux' p11-12
-
-        EXAMPLES:
-            sage: t = Tableau([[1,2,2,3],[2,3,5,5],[4,4,6],[5,6]])
-            sage: t2 = Tableau([[1,2],[3]])
-            sage: t.bump_multiply(t2)
-            [[1, 1, 2, 2, 3], [2, 2, 3, 5], [3, 4, 5], [4, 6, 6], [5]]
-        
-        """
-        if not isinstance(right, Tableau_class):
-            raise TypeError, "right must be a Tableau"
-
-        row = len(right)
-        product = copy.deepcopy(left)
-        while row > 0:
-            row -= 1
-            for i in right[row]:
-                product = product.bump(i)
-        return product
-
-    def slide_multiply(left, right):
-        """
-        Multiply two tableaux using jeu de taquin.
-
-        This product makes the set of tableaux into an associative monoid.
-        The empty tableaux is the unit in this monoid.
-        
-        Fulton, William. 'Young Tableaux' p15
-
-        EXAMPLES:
-            sage: t = Tableau([[1,2,2,3],[2,3,5,5],[4,4,6],[5,6]])
-            sage: t2 = Tableau([[1,2],[3]])
-            sage: t.slide_multiply(t2)
-            [[1, 1, 2, 2, 3], [2, 2, 3, 5], [3, 4, 5], [4, 6, 6], [5]]        
-        """
-        st = []
-        if len(left) == 0:
-            return right
-        else:
-            l = len(left[0])
-            
-        for row in range(len(right)):
-            st.append([None]*l + right[row])
-        for row in range(len(left)):
-            st.append(left[row])
-            
-        return sage.combinat.skew_tableau.SkewTableau(st).rectify()
-
-
-    def row_stabilizer(self):
-        """
-        Return the PermutationGroup corresponding to the row stabilizer
-        of self.
-
-        EXAMPLES:
-            sage: rs = Tableau([[1,2,3],[4,5]]).row_stabilizer()
-            sage: rs.order() == factorial(3)*factorial(2)
-            True
-            sage: PermutationGroupElement([(1,3,2),(4,5)]) in rs
-            True
-            sage: PermutationGroupElement([(1,4)]) in rs
-            False
-            sage: rs = Tableau([[1],[2],[3]]).row_stabilizer()
-            sage: rs.order()
-            1
-        """
-
-        gens = [ "()" ]
-        for i in range(len(self)):
-            for j in range(0, len(self[i])-1):
-                gens.append( (self[i][j], self[i][j+1]) )
-        return PermutationGroup( gens )
-
-    def column_stabilizer(self):
-        """
-        Return the PermutationGroup corresponding to the column stabilizer
-        of self.
-
-        EXAMPLES:
-            sage: cs = Tableau([[1,2,3],[4,5]]).column_stabilizer()
-            sage: cs.order() == factorial(2)*factorial(2)
-            True
-            sage: PermutationGroupElement([(1,3,2),(4,5)]) in cs
-            False
-            sage: PermutationGroupElement([(1,4)]) in cs
-            True
-        """
-
-        return self.conjugate().row_stabilizer()
-        
-
-
-def Tableaux(n=None):
-    """
-    Returns the combinatorial class of tableaux.  If n
-    is specified, then it returns the combinatoiral class
-    of all tableaux of size n.
-
-    EXAMPLES:
-        sage: T = Tableaux(); T
-        Tableaux
-        sage: [[1,2],[3,4]] in T
-        True
-        sage: [[1,2],[3]] in T
-        True
-        sage: [1,2,3] in T
-        False
-
-        sage: T = Tableaux(4); T
-        Tableaux of size 4
-        sage: [[1,2],[3,4]] in T
-        True
-        sage: [[1,2],[3]] in T
-        False
-        sage: [1,2,3] in T
-        False
-    """
-    if n == None:
-        return Tableaux_all()
-    else:
-        return Tableaux_n(n)
-
-class Tableaux_all(CombinatorialClass):
-    def __init__(self):
-        """
-        TESTS:
-            sage: T = Tableaux()
-            sage: T == loads(dumps(T))
-            True
-        """
-        pass
-    
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: T = Tableaux()   
-            sage: [[1,2],[3,4]] in T
-            True
-            sage: [[1,2],[3]] in T
-            True
-            sage: [1,2,3] in T
-            False
-        """
-        if isinstance(x, Tableau_class):
-            return True
-        
-        if not isinstance(x, __builtin__.list):
-            return False
-        
-        for row in x:
-            if not isinstance(row, __builtin__.list):
-                return False
-            
-        return True
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Tableaux())
-            'Tableaux'
-        """
-        return "Tableaux"
-
-    def list(self):
-        """
-        TESTS:
-            sage: Tableaux().list()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError
-        """
-        raise NotImplementedError
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: Tableaux().iterator()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError
-        """
-        raise NotImplementedError
-    
-
-class Tableaux_n(CombinatorialClass):
-    def __init__(self, n):
-        """
-        TESTS:
-            sage: T = Tableaux(3)
-            sage: T == loads(dumps(T))
-            True
-        """
-        self.n = n
-
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Tableaux(4))
-            'Tableaux of size 4'
-        """
-        return "Tableaux of size %s"%self.n
-    
-    def __contains__(self,x):
-        """
-        EXAMPLES:
-            sage: [[2,4],[1,3]] in Tableaux(3)
-            False
-            sage: [[2,4], [1]] in Tableaux(3)
-            True
-        """
-        return x in Tableaux() and sum(map(len, x)) == self.n
-    
-    def list(self):
-        """
-        TESTS:
-            sage: Tableaux(3).list()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError
-        """
-        raise NotImplementedError
-
-    def iterator(self):
-        """
-        TESTS:
-            sage: Tableaux(3).iterator()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError
-        """
-        raise NotImplementedError
-
-def StandardTableaux(n=None):
-    """
-    Returns the combinatorial class of standard tableaux.
-    If n is specified abd is an integer, then it returns
-    the combinatorial class of all standard tableaux of
-    size n.  If n is a partition, then it returns the class
-    of all standard tableaux of shape n.
-
-    EXAMPLES:
-        sage: ST = StandardTableaux(3); ST
-        Standard tableaux of size 3
-        sage: ST.first()
-        [[1, 2, 3]]
-        sage: ST.last()
-        [[1], [2], [3]]
-        sage: ST.count()
-        4
-        sage: ST.list()
-        [[[1, 2, 3]], [[1, 3], [2]], [[1, 2], [3]], [[1], [2], [3]]]
-
-        sage: ST = StandardTableaux([2,2]); ST
-        Standard tableaux of shape [2, 2]
-        sage: ST.first()
-        [[1, 3], [2, 4]]
-        sage: ST.last()
-        [[1, 2], [3, 4]]
-        sage: ST.count()
-        2
-        sage: ST.list()
-        [[[1, 3], [2, 4]], [[1, 2], [3, 4]]]
-    """
-    if n == None:
-        return StandardTableaux_all()
-    elif n in Partitions():
-        return StandardTableaux_partition(n)
-    else:
-        return StandardTableaux_n(n)
-
-class StandardTableaux_all(CombinatorialClass):
-    def __init__(self):
-        """
-        TESTS:
-            sage: ST = StandardTableaux()
-            sage: ST == loads(dumps(ST))
-            True
-        """
-        pass
-    
-    def __contains__(self, x):
-        """
-        EXAMPLES:
-            sage: [[1,1],[2,3]] in StandardTableaux()
-            False
-            sage: [[1,2],[3,4]] in StandardTableaux()
-            True
-            sage: [[1,3],[2,4]] in StandardTableaux()
-            True
-        """
-        if x not in Tableaux():
-            return False
-        else:
-            t = Tableau(x)
-            
-        #Check to make sure the first position is 1
-        fillings = []
-        for row in t:
-            fillings += row
-        fillings.sort()
-        if fillings != range(1, max(fillings)+1):
-            return False
-
-        #Check to make sure it is increasing along the rows
-        for row in t:
-            for i in range(1, len(row)):
-                if row[i] <= row[i-1]:
-                    return False
-
-        #Check to make sure it is increasing along the columns
-        conj = t.conjugate()
-        for row in conj:
-            for i in range(1, len(row)):
-                if row[i] <= row[i-1]:
-                    return False    
-
-        return True
-    
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(StandardTableaux())
-            'Standard tableaux'
-        """
-        return "Standard tableaux"
-
-    def list(self):
-        """
-        TESTS:
-            sage: StandardTableaux().list()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError
-        """
-        raise NotImplementedError
-
-
-class StandardTableaux_n(CombinatorialClass):
-    def __init__(self, n):
-        """
-        TESTS:
-            sage: ST = StandardTableaux(3)
-            sage: ST == loads(dumps(ST))
-            True
-        """
-        self.n = n
-
-    object_class = Tableau_class
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(StandardTableaux(3))
-            'Standard tableaux of size 3'
-        """
-        return "Standard tableaux of size %s"%self.n
-        
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: ST3 = StandardTableaux(3)
-            sage: all([st in ST3 for st in ST3])
-            True
-            sage: ST4 = StandardTableaux(4)
-            sage: filter(lambda x: x in ST3, ST4)
-            []
-        """
-        return x in StandardTableaux() and sum(map(len, x)) == self.n
-
-    def iterator(self):
-        """
-        EXAMPLES:
-            sage: StandardTableaux(1).list()
-            [[[1]]]
-            sage: StandardTableaux(2).list()
-            [[[1, 2]], [[1], [2]]]
-            sage: StandardTableaux(3).list()
-            [[[1, 2, 3]], [[1, 3], [2]], [[1, 2], [3]], [[1], [2], [3]]]
-            sage: StandardTableaux(4).list()
-            [[[1, 2, 3, 4]],
-             [[1, 3, 4], [2]],
-             [[1, 2, 4], [3]],
-             [[1, 2, 3], [4]],
-             [[1, 3], [2, 4]],
-             [[1, 2], [3, 4]],
-             [[1, 4], [2], [3]],
-             [[1, 3], [2], [4]],
-             [[1, 2], [3], [4]],
-             [[1], [2], [3], [4]]]
-        """
-        for p in Partitions(self.n):
-            for st in StandardTableaux(p):
-                yield st
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: StandardTableaux(3).count()
-            4
-            sage: ns = [1,2,3,4,5,6]
-            sage: sts = [StandardTableaux(n) for n in ns]
-            sage: all([st.count() == len(st.list()) for st in sts])
-            True
-        """
-        c = 0
-        for p in Partitions(self.n):
-            c += StandardTableaux(p).count()
-        return c
-
-    
-class StandardTableaux_partition(CombinatorialClass):
-    def __init__(self, p):
-        """
-        TESTS:
-            sage: ST = StandardTableaux([2,1,1])
-            sage: ST == loads(dumps(ST))
-            True
-        """
-        self.p = Partition(p)
-    
-    def __contains__(self, x):
-        """
-        EXAMPLES:
-            sage: ST = StandardTableaux([2,1,1])
-            sage: all([st in ST for st in ST])
-            True
-            sage: len(filter(lambda x: x in ST, StandardTableaux(4)))
-            3
-            sage: ST.count()
-            3
-
-        """
-        return x in StandardTableaux() and map(len,x) == self.p
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(StandardTableaux([2,1,1]))
-            'Standard tableaux of shape [2, 1, 1]'
-        """
-        return "Standard tableaux of shape %s"%str(self.p)
-    
-    def count(self):
-        r"""
-        Returns the number of standard Young tableaux associated with 
-        a partition pi
-
-        A formula for the number of Young tableaux associated with a given partition.
-        In each box, write the sum of one plus the number of boxes horizontally to the right
-        and vertically below the box (the hook length).
-        The number of tableaux is then n! divided by the product of all hook lengths.
-
-        For example, consider the partition [3,2,1] of 6 with Ferrers Diagram
-        * * *
-        * *
-        *
-        When we fill in the boxes with the hook lengths, we obtain
-        5 3 1
-        3 1
-        1
-        The hook length formula returns 6!/(5*3*1*3*1*1) = 16.
-
-        EXAMPLES:
-            sage: StandardTableaux([3,2,1]).count()
-            16
-            sage: StandardTableaux([2,2]).count()
-            2
-            sage: StandardTableaux([5]).count()
-            1
-            sage: StandardTableaux([6,5,5,3]).count()
-            6651216
-
-        REFERENCES:
-            http://mathworld.wolfram.com/HookLengthFormula.html
-        """
-        pi = self.p
-
-        number = factorial(sum(pi))
-        hook = pi.hook_lengths()
-        entry = 0
-
-        for row in range(len(pi)):
-            for col in range(pi[row]):
-                #Divide the hook length by the entry
-                number /= hook[row][col]
-
-        return number
-
-    def iterator(self):
-        r"""
-        An iterator for the standard Young tableaux associated to the
-        partition pi.
-
-        EXAMPLES:
-            sage: [p for p in StandardTableaux([2,2])]
-            [[[1, 3], [2, 4]], [[1, 2], [3, 4]]]
-            sage: [p for p in StandardTableaux([3,2])]
-            [[[1, 3, 5], [2, 4]],
-             [[1, 2, 5], [3, 4]],
-             [[1, 3, 4], [2, 5]],
-             [[1, 2, 4], [3, 5]],
-             [[1, 2, 3], [4, 5]]]
-
-        """
-
-        pi = self.p
-        #Set the intial tableaux by filling it in going down the columns
-        tableau = [[None]*n for n in pi]
-        size = sum(pi)
-        row = 0
-        col = 0
-        for i in range(size):
-            tableau[row][col] = i+1
-
-            #If we can move down, then do it;
-            #otherwise, move to the next column over
-            if ( row + 1 < len(pi) and col < pi[row+1]):
-                row += 1
-            else:
-                row = 0
-                col += 1
-
-        yield Tableau(tableau)
-
-        if self.count() == 1:
-            last_tableau = True
-        else:
-            last_tableau = False
-
-        while not last_tableau:
-            #Convert the tableau to "vector format"
-            #tableau_vector[i] is the row that number i
-            #is in
-            tableau_vector = [None]*size
-            for row in range(len(pi)):
-                for col in range(pi[row]):
-                    tableau_vector[tableau[row][col]-1] = row
-
-            #Locate the smallest integer j such that j is not
-            #in the lowest corner of the subtableau T_j formed by
-            #1,...,j.  This happens to be first j such that
-            #tableau_vector[j]<tableau_vector[j-1].
-            #l will correspond to the shape of T_j
-            l = [0]*size
-            l[0] = 1
-            j = 0
-            for i in range(1,size):
-                l[tableau_vector[i]] += 1
-                if ( tableau_vector[i] < tableau_vector[i-1] ):
-                    j = i
-                    break
-
-            #Find the last nonzero row of l and store it in k
-            i = size - 1
-            while ( l[i] == 0 ):
-                i -= 1
-            k = i
-
-            #Find a new row for the letter j (next lowest corner)
-            t = l[ 1 + tableau_vector[j] ]
-            i = k
-            while ( l[i] != t ):
-                i -= 1
-
-            #Move the letter j to row i
-            tableau_vector[j] = i
-            l[i] -= 1
-
-            #Fill in the columns of T_j using 1,...,j-1 in increasing order
-            m = 0
-            while ( m < j ):
-                r = 0
-                while ( l[r] != 0 ):
-                    tableau_vector[m] = r
-                    l[r] -= 1
-                    m += 1
-                    r += 1
-
-            #Convert the tableau vector back to the regular tableau
-            #format
-            row_count= [0]*len(pi)
-            start_positions = [sum(pi[:n]) for n in range(len(pi))]
-            tableau = [[None]*n for n in pi]
-
-            for i in range(size):
-                #print tableau_vector, tableau_vector[i], row_count[tableau_vector[i]]
-                tableau[tableau_vector[i]][row_count[tableau_vector[i]]] = i+1
-                row_count[tableau_vector[i]] += 1
-
-            yield Tableau(tableau)
-
-            #Check to see if we are at the last tableau
-            #The last tableau if given by filling in the
-            #partition along the rows.  For example, the
-            #last partition corresponding to [3,2] is
-            #[[1,2,3],
-            # [4,5]]
-            last_tableau = True
-            i = 1
-            for row in range(len(pi)):
-                for col in range(pi[row]):
-                    if tableau[row][col] != i:
-                        last_tableau = False
-                    i += 1
-
-
-        return
-
-
-    def list(self):
-        r"""
-        Returns a list of the standard Young tableau associated with a
-        partition p.
-
-        EXAMPLES:
-            sage: StandardTableaux([2,2]).list()
-            [[[1, 3], [2, 4]], [[1, 2], [3, 4]]]
-            sage: StandardTableaux([5]).list()
-            [[[1, 2, 3, 4, 5]]]
-            sage: StandardTableaux([3,2,1]).list()
-            [[[1, 4, 6], [2, 5], [3]],
-             [[1, 3, 6], [2, 5], [4]],
-             [[1, 2, 6], [3, 5], [4]],
-             [[1, 3, 6], [2, 4], [5]],
-             [[1, 2, 6], [3, 4], [5]],
-             [[1, 4, 5], [2, 6], [3]],
-             [[1, 3, 5], [2, 6], [4]],
-             [[1, 2, 5], [3, 6], [4]],
-             [[1, 3, 4], [2, 6], [5]],
-             [[1, 2, 4], [3, 6], [5]],
-             [[1, 2, 3], [4, 6], [5]],
-             [[1, 3, 5], [2, 4], [6]],
-             [[1, 2, 5], [3, 4], [6]],
-             [[1, 3, 4], [2, 5], [6]],
-             [[1, 2, 4], [3, 5], [6]],
-             [[1, 2, 3], [4, 5], [6]]]
-
-        """
-        return [y for y in self]
-          
-
-    def random(self):
-        """
-        Returns a random standard tableau of shape p using the
-        Green-Nijenhuis-Wilf Algorithm.
-
-
-        EXAMPLES:
-            sage: StandardTableaux([2,2]).random() #random
-            [[1, 2], [3, 4]]
-        """
-
-        p = self.p
-
-        t = [[None]*n for n in p]
-
-
-        #Get the cells in the 
-        cells = []
-        for i in range(len(p)):
-            for j in range(p[i]):
-                cells.append([i,j])
-
-
-        done = False
-        m = sum(p)
-        while m > 0:
-
-            #Choose a cell at random
-            cell = random.choice(cells)
-
-
-            #Find a corner
-            inner_corners = p.corners()
-            while cell not in inner_corners:
-                hooks = []
-                for k in range(cell[1], p[cell[0]]):
-                    hooks.append([cell[0], k])
-                for k in range(cell[0], len(p)):
-                    if p[k] > cell[1]:
-                        hooks.append([k, cell[1]])
-
-                cell = random.choice(hooks)
-
-
-            #Assign m to cell
-            t[cell[0]][cell[1]] = m
-
-            p = p.remove_box(cell[0])
-
-            cells.remove(cell)
-
-            m -= 1
-
-        return Tableau(t)
-
-
-## def heights(t):
-##     """
-##     Returns a list of the heights of the tableau t.
-
-##     EXAMPLES:
-##         sage: tableau.heights([[1,2],[3,2])
-##         [2, 2]
-##         sage: tableau.heights([3,2,1])
-##         [3, 2, 1]
-##         sage: tableau.heights([3,1])
-##         [2, 1, 1]
-##     """
-
-##     return partition.heights(shape(t))
-
-
-
-
-
-##########################
-# Semi-standard tableaux #
-##########################
-
-def SemistandardTableaux(p=None, mu=None):
-    """
-    Returns the combinatorial class of semistandard tableaux.
-
-    If p is specified and is a partition, then it returns the
-    class of semistandard tableaux of shape p (and max entry
-    sum(p))
-    
-    If p is specified and is an integer, it returns the class
-    of semistandard tableaux of size p.
-
-    If mu is also specified, then it returns the class of
-    semistandard tableaux with evaluation/content mu.
-
-    EXAMPLES:
-        sage: SST = SemistandardTableaux([2,1]); SST
-        Semistandard tableaux of shape [2, 1]
-        sage: SST.list()
-        [[[1, 2], [3]], [[1, 3], [2]], [[1, 2], [2]], [[1, 1], [2]]]
-        
-        sage: SST = SemistandardTableaux(3); SST
-        Semistandard tableaux of size 3
-        sage: SST.list()
-        [[[1, 2, 3]],
-         [[1, 2, 2]],
-         [[1, 1, 2]],
-         [[1, 1, 1]],
-         [[1, 2], [3]],
-         [[1, 3], [2]],
-         [[1, 2], [2]],
-         [[1, 1], [2]],
-         [[1], [2], [3]]]
-    """
-    if p == None:
-        return SemistandardTableaux_all()
-    elif p in Partitions():
-        if mu == None:
-            return SemistandardTableaux_p(p)
-        else:
-            if sum(p) != sum(mu):
-                #Error size mismatch
-                raise TypeError, "p and mu must be of the same size"
-            else:
-                return SemistandardTableaux_pmu(p, mu)
-    elif isinstance(p, (int, Integer)):
-        if mu == None:
-            return SemistandardTableaux_n(p)
-        else:
-            if p != sum(mu):
-                #Error size mismatch
-                raise TypeError, "mu must be of size p (= %s)"%self.p
-            else:
-                return SemistandardTableaux_nmu(p, mu)
-    else:
-        raise ValueError
-
-class SemistandardTableaux_all(CombinatorialClass):
-    def __init__(self):
-        """
-        TESTS:
-            sage: SST = SemistandardTableaux()
-            sage: SST == loads(dumps(SST))
-            True
-        """
-        
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: [[1,2],[1]] in SemistandardTableaux()
-            False
-            sage: SST = SemistandardTableaux()
-            sage: all([st in SST for st in StandardTableaux(4)])
-            True
-            sage: [[1,1],[2]] in SemistandardTableaux()
-            True
-        """
-        if x not in Tableaux():
-            return False
-        else:
-            t = Tableau(x)
-            
-        #Check to make sure the first position is 1
-        fillings = []
-        for row in t:
-            for i in row:
-                if not isinstance(i, (int, Integer)):
-                    return False
-
-        #Check to make sure it is non-decreasing along the rows
-        for row in t:
-            for i in range(1, len(row)):
-                if row[i] < row[i-1]:
-                    return False
-
-        #Check to make sure it is increasing along the columns
-        conj = t.conjugate()
-        for row in conj:
-            for i in range(1, len(row)):
-                if row[i] <= row[i-1]:
-                    return False    
-
-        return True
-
-    def list(self):
-        """
-        TESTS:
-            sage: SemistandardTableaux().list()
-            Traceback (most recent call last):
-            ...
-            NotImplementedError
-        """
-        raise NotImplementedError
-
-class SemistandardTableaux_n(CombinatorialClass):
-    def __init__(self, n):
-        """
-        TESTS:
-            sage: SST = SemistandardTableaux(3)
-            sage: SST == loads(dumps(SST))
-            True
-        """
-        self.n = n
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SemistandardTableaux(3))
-            'Semistandard tableaux of size 3'
-        """
-        return "Semistandard tableaux of size %s"%str(self.n)
-
-    def __contains__(self, x):
-        """
-        EXAMPLES:
-            sage: [[1,2],[3,3]] in SemistandardTableaux(3)
-            False
-            sage: [[1,2],[3,3]] in SemistandardTableaux(4)
-            True
-            sage: SST = SemistandardTableaux(4)
-            sage: all([sst in SST for sst in SST])
-            True
-        """
-        return x in SemistandardTableaux() and sum(map(len, x)) == self.n
-
-    object_class = Tableau_class
-        
-    def count(self):
-        """
-        EXAMPLES:
-            sage: SemistandardTableaux(3).count()
-            9
-            sage: SemistandardTableaux(4).count()
-            33
-            sage: ns = range(1, 6)
-            sage: ssts = [ SemistandardTableaux(n) for n in ns ]
-            sage: all([sst.count() == len(sst.list()) for sst in ssts])
-            True
-        """
-        c = 0
-        for part in Partitions(self.n):
-            c += SemistandardTableaux(part).count()
-        return c
-
-    def iterator(self):
-        """
-        EXAMPLES:
-            sage: SemistandardTableaux(2).list()
-            [[[1, 2]], [[1, 1]], [[1], [2]]]
-            sage: SemistandardTableaux(3).list()
-            [[[1, 2, 3]],
-             [[1, 2, 2]],
-             [[1, 1, 2]],
-             [[1, 1, 1]],
-             [[1, 2], [3]],
-             [[1, 3], [2]],
-             [[1, 2], [2]],
-             [[1, 1], [2]],
-             [[1], [2], [3]]]
-        """
-        for part in Partitions(self.n):
-            for sst in SemistandardTableaux(part):
-                yield sst
-
-class SemistandardTableaux_pmu(CombinatorialClass):
-    def __init__(self, p, mu):
-        """
-        TESTS:
-            sage: SST = SemistandardTableaux([2,1], [2,1])
-            sage: SST == loads(dumps(SST))
-            True
-        """
-        self.p = p
-        self.mu = mu
-
-    object_class = Tableau_class
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SemistandardTableaux([2,1],[2,1]))
-            'Semistandard tableaux of shape [2, 1] and evaluation [2, 1]'
-        """
-        return "Semistandard tableaux of shape %s and evaluation %s"%(self.p, self.mu)
-
-    def __contains__(self, x):
-        """
-        EXAMPLES:
-            sage: SST = SemistandardTableaux([2,1], [2,1])
-            sage: all([sst in SST for sst in SST])
-            True
-            sage: len(filter(lambda x: x in SST, SemistandardTableaux(3)))
-            1
-            sage: SST.count()
-            1
-        """
-        if not x in SemistandardTableaux(self.p):
-            return False
-        n = sum(self.p)
-
-        if n == 0 and len(x) == 0:
-            return True
-
-        content = {}
-        for row in x:
-            for i in row:
-                content[i] = content.get(i, 0) + 1
-        content_list = [0]*int(max(content))
-
-        for key in content:
-            content_list[key-1] = content[key]
-
-        if content_list != self.mu:
-            return False
-
-        return True
-        
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: SemistandardTableaux([2,2], [2, 1, 1]).count()
-            1
-            sage: SemistandardTableaux([2,2,2], [2, 2, 1,1]).count()
-            1
-            sage: SemistandardTableaux([2,2,2], [2, 2, 2]).count()
-            1
-            sage: SemistandardTableaux([3,2,1], [2, 2, 2]).count()
-            2
-        """
-        return symmetrica.kostka_number(self.p,self.mu)
-
-
-    def list(self):
-        """
-        EXAMPLES:
-            sage: SemistandardTableaux([2,2], [2, 1, 1]).list()
-            [[[1, 1], [2, 3]]]
-            sage: SemistandardTableaux([2,2,2], [2, 2, 1,1]).list()
-            [[[1, 1], [2, 2], [3, 4]]]
-            sage: SemistandardTableaux([2,2,2], [2, 2, 2]).list()
-            [[[1, 1], [2, 2], [3, 3]]]
-            sage: SemistandardTableaux([3,2,1], [2, 2, 2]).list()
-            [[[1, 1, 2], [2, 3], [3]], [[1, 1, 3], [2, 2], [3]]]
-        """
-        return symmetrica.kostka_tab(self.p, self.mu)
-        
-    
-class SemistandardTableaux_p(CombinatorialClass):
-    def __init__(self, p):
-        """
-        TESTS:
-            sage: SST = SemistandardTableaux([2,1])
-            sage: SST == loads(dumps(SST))
-            True
-        """
-        self.p = p
-
-    object_class = Tableau_class
-
-    def __contains__(self, x):
-        """
-        EXAMPLES:
-            sage: SST = SemistandardTableaux([2,1])
-            sage: all([sst in SST for sst in SST])
-            True
-            sage: len(filter(lambda x: x in SST, SemistandardTableaux(3)))
-            4
-            sage: SST.count()
-            4
-        """
-        return x in SemistandardTableaux_all() and map(len, x) == self.p
-    
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SemistandardTableaux([2,1]))
-            'Semistandard tableaux of shape [2, 1]'
-        """
-        return "Semistandard tableaux of shape %s" % str(self.p)
-
-   
-    def iterator(self):
-        """
-        An iterator for the semistandard partitions of shape p.
-
-        EXAMPLES:
-            sage: SemistandardTableaux([3]).list()
-            [[[1, 2, 3]], [[1, 2, 2]], [[1, 1, 2]], [[1, 1, 1]]]
-            sage: SemistandardTableaux([2,1]).list()
-            [[[1, 2], [3]], [[1, 3], [2]], [[1, 2], [2]], [[1, 1], [2]]]
-            sage: SemistandardTableaux([1,1,1]).list()
-            [[[1], [2], [3]]]
-        """
-        for c in Compositions(sum(self.p)):
-            for sst in SemistandardTableaux(self.p, c):
-                yield sst
-
-class SemistandardTableaux_nmu(CombinatorialClass):
-    def __init__(self, n, mu):
-        """
-        TESTS:
-            sage: SST = SemistandardTableaux(3, [2,1])
-            sage: SST == loads(dumps(SST))
-            True
-        """
-        self.n = n
-        self.mu = mu
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(SemistandardTableaux(3, [2,1]))
-            'Semistandard tableaux of size 3 and evaluation [2, 1]'
-        """
-        return "Semistandard tableaux of size %s and evaluation %s"%(self.n, self.mu)
-
-    def iterator(self):
-        """
-        EXAMPLES:
-            sage: SemistandardTableaux(3, [2,1]).list()
-            [[[1, 1, 2]], [[1, 1], [2]]]
-            sage: SemistandardTableaux(4, [2,2]).list()
-            [[[1, 1, 2, 2]], [[1, 1, 2], [2]], [[1, 1], [2, 2]]]
-        """
-        for p in Partitions(self.n):
-            for sst in SemistandardTableaux_pmu(p, self.mu):
-                yield sst
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: SemistandardTableaux(3, [2,1]).count()
-            2
-            sage: SemistandardTableaux(4, [2,2]).count()
-            3
-        """
-        c = 0
-        for p in Partitions(self.n):
-            c += SemistandardTableaux_pmu(p, self.mu).count()
-        return c
-
-    def __contains__(self, x):
-        """
-        TESTS:
-            sage: SST = SemistandardTableaux(6, [2,2,2])
-            sage: all([sst in SST for sst in SST])
-            True
-            sage: all([sst in SST for sst in SemistandardTableaux([3,2,1],[2,2,2])])
-            True
-        """
-        return x in SemistandardTableaux_all() and x in SemistandardTableaux(map(len, x), self.mu)
Index: age/combinat/tools.py
===================================================================
--- sage/combinat/tools.py	(revision 6439)
+++ 	(revision )
@@ -1,54 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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/
-#*****************************************************************************
-
-def transitive_ideal(f, x):
-    """
-    Given an initial value x and a successor function f,
-    return a list containing x and all of its successors.
-    The successor function should return a list of all the
-    successors of f.
-
-    Note that if x has an infinite number of successors,
-    transitive_ideal won't return.
-
-    EXAMPLES:
-        sage: def f(x):
-        ...       if x > 0:
-        ...           return [x-1]
-        ...       else:
-        ...           return []
-        sage: sage.combinat.tools.transitive_ideal(f, 10)
-        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-    """
-
-    #succ_rec = lambda g: map(succ_rec, f(g))
-    #succ_rec(x)
-    result = [x]
-    known  = [x]
-    todo   = [x]
-
-    while todo != []:
-        y = todo[0]
-        todo.remove(y)
-        for z in f(y):
-            if z == [] or z in known:
-                continue
-            result.append(z)
-            known.append(z)
-            todo.append(z)
-
-
-    result.sort()
-    return result
Index: age/combinat/tuple.py
===================================================================
--- sage/combinat/tuple.py	(revision 6439)
+++ 	(revision )
@@ -1,173 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 combinat import CombinatorialClass
-from sage.interfaces.all import gap
-from sage.rings.all import ZZ
-
-def Tuples(S,k):
-    """
-    Returns the combinatorial class of ordered tuples of S of length k.
-
-    An ordered tuple of length k of set is an ordered selection with 
-    repetition and is represented by a list of length k containing 
-    elements of set.
-
-    EXAMPLES:
-        sage: S = [1,2]
-        sage: Tuples(S,3).list()
-	[[1, 1, 1], [2, 1, 1], [1, 2, 1], [2, 2, 1], [1, 1, 2], [2, 1, 2], [1, 2, 2], [2, 2, 2]]
-        sage: mset = ["s","t","e","i","n"]
-        sage: Tuples(mset,2).list()
-	[['s', 's'], ['t', 's'], ['e', 's'], ['i', 's'], ['n', 's'], ['s', 't'], ['t', 't'],
-	 ['e', 't'], ['i', 't'], ['n', 't'], ['s', 'e'], ['t', 'e'], ['e', 'e'], ['i', 'e'],
-         ['n', 'e'], ['s', 'i'], ['t', 'i'], ['e', 'i'], ['i', 'i'], ['n', 'i'], ['s', 'n'],
-	 ['t', 'n'], ['e', 'n'], ['i', 'n'], ['n', 'n']]
-
-
-	sage: K.<a> = GF(4, 'a')
-	sage: mset = [x for x in K if x!=0]
-	sage: Tuples(mset,2).list()
-        [[a, a], [a + 1, a], [1, a], [a, a + 1], [a + 1, a + 1], [1, a + 1], [a, 1], [a + 1, 1], [1, 1]]
-    """
-    return Tuples_sk(S,k)
-
-class Tuples_sk(CombinatorialClass):
-    def __init__(self, S, k):
-        """
-        TESTS:
-            sage: T = Tuples([1,2,3],2)
-            sage: T == loads(dumps(T))
-            True
-        """
-        self.S = S
-        self.k = k
-        self._index_list = map(S.index, S)
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Tuples([1,2,3],2))
-            'Tuples of [1, 2, 3] of length 2'
-        """
-        return "Tuples of %s of length %s"%(self.S, self.k)
-
-    def iterator(self):
-        """
-        EXAMPLES:
-            sage: S = [1,2]
-            sage: Tuples(S,3).list()
-            [[1, 1, 1], [2, 1, 1], [1, 2, 1], [2, 2, 1], [1, 1, 2], [2, 1, 2], [1, 2, 2], [2, 2, 2]]
-            sage: mset = ["s","t","e","i","n"]
-            sage: Tuples(mset,2).list()
-            [['s', 's'], ['t', 's'], ['e', 's'], ['i', 's'], ['n', 's'], ['s', 't'], ['t', 't'],
-            ['e', 't'], ['i', 't'], ['n', 't'], ['s', 'e'], ['t', 'e'], ['e', 'e'], ['i', 'e'],
-            ['n', 'e'], ['s', 'i'], ['t', 'i'], ['e', 'i'], ['i', 'i'], ['n', 'i'], ['s', 'n'],
-            ['t', 'n'], ['e', 'n'], ['i', 'n'], ['n', 'n']]
-        """
-        S = self.S
-        k = self.k
-        import copy
-        if k<=0:
-            yield []
-            return
-        if k==1:
-            for x in S:
-                yield [x]
-            return
-
-        for s in S:
-            for x in Tuples_sk(S,k-1):
-                y = copy.copy(x)
-                y.append(s)
-                yield y
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: S = [1,2,3,4,5]
-            sage: Tuples(S,2).count()
-            25
-            sage: S = [1,1,2,3,4,5]
-            sage: Tuples(S,2).count()
-            25
-
-        """
-        ans=gap.eval("NrTuples(%s,%s)"%(self._index_list,ZZ(self.k)))
-        return ZZ(ans)
-
-
-
-def UnorderedTuples(S,k):
-    """
-    Returns the combinatorial class of unordered tuples of S
-    of length k.
-
-    An unordered tuple of length k of set is a unordered selection  
-    with repetitions of set and is represented by a sorted list of 
-    length k containing elements from set.
-
-    EXAMPLES:
-        sage: S = [1,2]
-        sage: UnorderedTuples(S,3).list()
-        [[1, 1, 1], [1, 1, 2], [1, 2, 2], [2, 2, 2]]
-        sage: UnorderedTuples(["a","b","c"],2).list()
-        [['a', 'a'], ['a', 'b'], ['a', 'c'], ['b', 'b'], ['b', 'c'], ['c', 'c']]
-    """
-    return UnorderedTuples_sk(S,k)
-
-
-class UnorderedTuples_sk(CombinatorialClass):
-    def __init__(self, S, k):
-        """
-        TESTS:
-            sage: T = Tuples([1,2,3],2)
-            sage: T == loads(dumps(T))
-            True
-        """
-        self.S = S
-        self.k = k
-        self._index_list = map(S.index, S)
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(UnorderedTuples([1,2,3],2))
-            'Unordered tuples of [1, 2, 3] of length 2'
-        """
-        return "Unordered tuples of %s of length %s"%(self.S, self.k)
-
-    def list(self):
-        """
-        EXAMPLES:
-            sage: S = [1,2]
-            sage: UnorderedTuples(S,3).list()
-            [[1, 1, 1], [1, 1, 2], [1, 2, 2], [2, 2, 2]]
-            sage: UnorderedTuples(["a","b","c"],2).list()
-            [['a', 'a'], ['a', 'b'], ['a', 'c'], ['b', 'b'], ['b', 'c'], ['c', 'c']]
-        """
-        ans=gap.eval("UnorderedTuples(%s,%s)"%(self._index_list,ZZ(self.k)))
-        return map(lambda l: map(lambda i: self.S[i], l), eval(ans))
-
-    def count(self):
-        """
-        EXAMPLES:
-            sage: S = [1,2,3,4,5]
-            sage: UnorderedTuples(S,2).count()
-            15
-        """
-        ans=gap.eval("NrUnorderedTuples(%s,%s)"%(self._index_list,ZZ(self.k)))
-        return ZZ(ans)
Index: age/combinat/word.py
===================================================================
--- sage/combinat/word.py	(revision 6439)
+++ 	(revision )
@@ -1,623 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2007 Mike Hansen <mhansen@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 sage.combinat.generator as generator
-from sage.rings.arith import binomial
-from sage.rings.integer import Integer
-from sage.misc.mrange import xmrange
-import sage.combinat.permutation
-import itertools
-import __builtin__
-from combinat import CombinatorialClass, CombinatorialObject
-
-
-def Words(alphabet, k):
-    """
-    Returns the combinatorial class of words of length k
-    from alphabet.
-
-    EXAMPLES:
-        sage: w = Words([1,2,3], 2); w
-        Words from [1, 2, 3] of length 2
-        sage: w.count()
-        9
-        sage: w.list()
-        [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
-    """
-    if isinstance(alphabet, (int, Integer)):
-        alphabet = range(1,alphabet+1)
-
-    return Words_alphabetk(alphabet, k)
-
-class Words_alphabetk(CombinatorialClass):
-    def __init__(self, alphabet, k):
-        """
-        TESTS:
-            sage: import sage.combinat.word as word
-            sage: w = word.Words_alphabetk([1,2,3], 2); w
-            Words from [1, 2, 3] of length 2
-            sage: w.count()
-            9
-        """
-        self.alphabet = alphabet
-        self.k = k
-
-    def __repr__(self):
-        """
-        TESTS:
-            sage: repr(Words([1,2,3], 2))
-            'Words from [1, 2, 3] of length 2'
-        """
-        return "Words from %s of length %s"%(self.alphabet, self.k)
-
-
-    def count(self):
-        r"""
-        Returns the number of words of length n from
-        alphabet.
-
-        EXAMPLES:
-            sage: Words(['a','b','c'], 4).count()
-            81
-            sage: Words(3, 4).count()
-            81
-            sage: Words(0,0).count()
-            1
-            sage: Words(5,0).count()
-            1
-            sage: Words(['a','b','c'],0).count()
-            1
-            sage: Words(0,1).count()
-            0
-            sage: Words(5,1).count()
-            5
-            sage: Words(['a','b','c'],1).count()
-            3
-            sage: Words(7,13).count()
-            96889010407
-            sage: Words(['a','b','c','d','e','f','g'],13).count()
-            96889010407
-
-        """
-        n = len(self.alphabet)
-        return n**self.k
-
-    def iterator(self):
-        """
-        Returns an iterator for all of the words
-        of length k from alphabet. The iterator
-        outputs the words in lexicographic order.
-
-        TESTS:
-            sage: [w for w in Words(['a', 'b'], 2)] 
-            [['a', 'a'], ['a', 'b'], ['b', 'a'], ['b', 'b']]
-            sage: [w for w in Words(['a', 'b'], 0)]
-            [[]]
-            sage: [w for w in Words([], 3)]
-            []
-        """
-
-        n = len(self.alphabet)
-
-        if self.k == 0:
-            yield []
-            return
-
-        for w in xmrange([n]*self.k):
-            yield map(lambda x: self.alphabet[x], w)
-
-
-def alphabet_order(alphabet):
-    """
-    Returns the ordering function of the alphabet A.
-    The function takes two elements x and y of A and
-    returns True if x occurs before y in A.
-
-    EXAMPLES:
-        sage: f = word.alphabet_order(['a','b','c'])
-        sage: f('a', 'b')
-        True
-        sage: f('c', 'a')
-        False
-        sage: f('b', 'b')
-        False
-
-    """
-
-    return lambda x,y: alphabet.index(x) < alphabet.index(y)
-
-
-
-def standard(w, alphabet = None, ordering = None):
-    """
-    Returns the standard permutation of the word
-    w on the ordered alphabet.  It is defined as
-    the permutation with exactly the same number of
-    inversions as w.
-
-    By default, the letters are ordered using <.  A
-    custom ordering can be specified by passing an
-    ordering function into ordering.
-
-    EXAMPLES:
-        sage: word.standard([1,2,3,2,2,1,2,1])
-        [1, 4, 8, 5, 6, 2, 7, 3]
-    """
-
-    if alphabet == None:
-        alphabet = range(1,max(w)+1)
-        
-    if ordering == None:
-        ordering = lambda x,y: x < y
-
-    def ordering_cmp(x,y):
-        """
-        Returns -1 if x < y under ordering otherwise it returns 1.
-        """
-        if ordering(x,y):
-            return -1
-        else:
-            return 1
-
-
-    d = evaluation_dict(w)
-    keys = d.keys()
-    keys.sort(cmp=ordering_cmp)
-
-    offset = 0
-    temp = 0
-    for k in keys:
-        temp = d[k]
-        d[k] = offset
-        offset += temp
-
-    result = []
-    for l in w:
-        d[l] += 1
-        result.append(d[l])
-
-    return sage.combinat.permutation.Permutation(result)
-    
-    
-def evaluation_dict(w):
-    """
-    Returns a dictionary that represents the evalution
-    of the word w.
-
-    EXAMPLES:
-        sage: word.evaluation_dict([2,1,4,2,3,4,2])
-        {1: 1, 2: 3, 3: 1, 4: 2}
-        sage: d = word.evaluation_dict(['b','a','d','b','c','d','b'])
-        sage: map(lambda i: d[i], ['a','b','c','d'])
-        [1, 3, 1, 2]
-        sage: word.evaluation_dict([])
-        {}
-
-    """
-
-    d = {}
-    for l in w:
-        if l not in d:
-            d[l] = 1
-        else:
-            d[l] += 1
-
-    return d
-
-def evaluation_sparse(w):
-    """
-
-    EXAMPLES:
-        sage: word.evaluation_sparse([4,4,2,5,2,1,4,1])
-        [[1, 2], [2, 2], [4, 3], [5, 1]]
-    """
-    ed = evaluation_dict(w)
-    keys = ed.keys()
-    keys.sort()
-    return [[x, ed[x]] for x in keys]
-
-def evaluation_partition(w):
-    """
-    Returns the evaluation of the word w as a partition.
-
-    EXAMPLE:
-        sage: word.evaluation_partition([2,1,4,2,3,4,2])
-        [3, 2, 1, 1]
-    """
-
-    d = evaluation_dict(w)
-    p = d.values()
-    p.sort(reverse=True)
-    return p
-
-def evaluation(w, alphabet=None):
-    r"""
-    Returns the evalutation of the word as a list.
-    Either the word must be a word of integers or you
-    must provide the alphabet as a list.
-
-    EXAMPLES:
-        sage: word.evaluation(['b','a','d','b','c','d','b'],['a','b','c','d','e'])
-        [1, 3, 1, 2, 0]
-        sage: word.evaluation([1,2,2,1,3])
-        [2, 2, 1]
-    """
-
-    if alphabet == None:
-        if len(w) == 0:
-            alpha = 0
-        else:
-            alpha = max(w)
-
-        e = [0] * alpha
-
-        for letter in w:
-            e[letter-1] += 1
-        return e
-
-    else:
-        d = evaluation_dict(w)
-        e = [0] * len(alphabet)
-        indices = {}
-        for i in range(len(alphabet)):
-            indices[alphabet[i]] = i
-        for l in w:
-            if l in d:
-                e[indices[l]] += 1
-        return e
-
-def from_standard_and_evaluation(sp, e, alphabet=None):
-    """
-    Returns the word given by the standard permutation
-    sp and the evaluation e.
-
-    EXAMPLES:
-        sage: a = [1,2,3,2,2,1,2,1]
-        sage: e = word.evaluation(a)
-        sage: sp = word.standard(a)
-        sage: b = word.from_standard_and_evaluation(sp, e)
-        sage: b
-        [1, 2, 3, 2, 2, 1, 2, 1]
-        sage: a == b
-        True
-
-    """
-
-    if sum(e) != len(sp):
-        return
-
-    if alphabet == None:
-        alphabet = range(1, len(e)+1)
-    elif isinstance(alphabet,Integer):
-        alphabet = range(1, alphabet+1)
-
-    part_sum = 0
-    subs = []
-    word = sp[:]
-    for i in range(len(e)):
-        next_part_sum = part_sum + e[i]
-        for k in range(part_sum, next_part_sum):
-            subs.append([k+1,alphabet[i]])
-        part_sum = next_part_sum
-
-    for sub in subs:
-        word[word.index(sub[0])] = sub[1]
-
-    return word
-
-def swap(w,i,j=None):
-   """
-   Returns the word w with entries at positions i and
-   j swapped.  By default, j = i+1.
-
-   EXAMPLES:
-       sage: word.swap([1,2,3],0,2)
-       [3, 2, 1]
-       sage: word.swap([1,2,3],1)
-       [1, 3, 2]
-   """
-   if j == None:
-       j = i+1
-   new = w[:]
-   (new[i], new[j]) = (new[j], new[i])
-   return new
-
-def swap_increase(w, i):
-    """
-    Returns the word w with positions i and i+1 exchanged
-    if w[i] > w[i+1].  Otherwise, it returns w.
-
-    EXAMPLES:
-        sage: word.swap_increase([1,3,2],0)
-        [1, 3, 2]
-        sage: word.swap_increase([1,3,2],1)
-        [1, 2, 3]
-
-    """
-
-    if w[i] > w[i+1]:
-        return swap(w,i)
-    else:
-        return w
-
-def swap_decrease(w, i):
-    """
-    Returns the word w with positions i and i+1 exchanged
-    if w[i] < w[i+1].  Otherwise, it returns w.
-
-    EXAMPLES:
-        sage: word.swap_decrease([1,3,2],0)
-        [3, 1, 2]
-        sage: word.swap_decrease([1,3,2],1)
-        [1, 3, 2]
-
-    """
-
-    if w[i] < w[i+1]:
-        return swap(w,i)
-    else:
-        return w
-
-def lex_less(w1,w2):
-    """
-    Returns true if the word w1 is lexicographically
-    less than w2.  It is restricted to words whose
-    letters can be compared by <.
-
-    EXAMPLES:
-        sage: word.lex_less([1,2,3],[1,3,2])
-        True
-        sage: word.lex_less([3,2,1],[1,2,3])
-        False
-    """
-
-    i = 0
-    while (i <= len(w1) ) and (i <= len(w2)) and (w1[i] == w2[i]):
-        i += 1
-
-    if i > len(w2):
-        return False
-    if i > len(w1):
-        return True
-
-    return w1[i] < w2[i]
-
-def lex_cmp(w1,w2):
-    """
-    Returns -1 if the word w1 is lexicographically
-    less than w2; otherwise, it returns 1.
-    It is restricted to words whose
-    letters can be compared by <.
-
-    Useful to pass into Python's sort()
-
-    EXAMPLES:
-        sage: word.lex_cmp([1,2,3],[1,3,2])
-        -1
-        sage: word.lex_cmp([3,2,1],[1,2,3])
-        1
-    """
-    if lex_less(w1, w2):
-        return -1
-    else:
-        return 1
-
-def deg_lex_less(w1,w2):
-    """
-    Returns true if the word w1 is degree
-    lexicographically less than w2.  It is
-    restricted to words whose letters can be
-    compared by < as well as summed.
-
-    EXAMPLES:
-        sage: word.deg_lex_less([1,2,3],[1,3,2])
-        True
-        sage: word.deg_lex_less([1,2,4],[1,3,2])
-        False
-        sage: word.deg_lex_less([3,2,1],[1,2,3])
-        False
-    """
-
-    d1 = sum(w1)
-    d2 = sum(w2)
-
-    if d1 != d2:
-        return d1 < d2
-
-    return lex_less(w1,w2)
-
-def inv_lex_less(w1, w2):
-    """
-    Returns true if the word w1 is inverse
-    lexicographically less than w2.  It is
-    restricted to words whose letters can be
-    compared by <.
-
-    EXAMPLES:
-        sage: word.inv_lex_less([1,2,4],[1,3,2])
-        False
-        sage: word.inv_lex_less([3,2,1],[1,2,3])
-        True
-    """
-    if len(w1) != len(w2):
-        return len(w1) < len(w2)
-
-    for i in reversed(range(0,len(w1))):
-        if w1[i] != w2[i]:
-            return w1[i] < w2[i]
-
-    return False
-            
-
-
-def deg_inv_lex_less(w1,w2):
-    """
-    Returns true if the word w1 is degree inverse
-    lexicographically less than w2.  It is
-    restricted to words whose letters can be
-    compared by < as well as summed.
-
-    EXAMPLES:
-        sage: word.deg_inv_lex_less([1,2,4],[1,3,2])
-        False
-        sage: word.deg_inv_lex_less([3,2,1],[1,2,3])
-        True
-    """
-
-    d1 = sum(w1)
-    d2 = sum(w2)
-
-    if d1 != d2:
-        return d1 < d2
-
-    return inv_lex_less(w1,w2)
-
-
-def rev_lex_less(w1,w2):
-    """
-    Returns true if the word w1 is reverse
-    lexicographically less than w2.  It is
-    restricted to words whose letters can be
-    compared by <.
-
-    EXAMPLES:
-        sage: word.rev_lex_less([1,2,4],[1,3,2])
-        True
-        sage: word.rev_lex_less([3,2,1],[1,2,3])
-        False
-    """
-
-    if len(w1) != len(w2):
-        return len(w1) > len(w2)
-
-    for i in reversed(range(0,len(w1))):
-        if w1[i] != w2[i]:
-            return w1[i] > w2[i]
-
-    return False
-
-
-def deg_rev_lex_less(w1, w2):
-    """
-    Returns true if the word w1 is degree reverse
-    lexicographically less than w2.  It is
-    restricted to words whose letters can be
-    compared by < as well as summed.
-
-    EXAMPLES:
-        sage: word.deg_rev_lex_less([1,2,4],[1,3,2])
-        False
-        sage: word.deg_rev_lex_less([3,2,1],[1,2,3])
-        False
-    """
-
-    d1 = sum(w1)
-    d2 = sum(w2)
-
-    if d1 != d2:
-        return d1 < d2
-
-    return rev_lex_less(w1,w2)
-
-
-def min_lex(l):
-    """Returns the minimal element in lexicographic
-    order of a l of words.
-
-    EXAMPLES:
-        sage: word.min_lex([[1,2,3],[1,3,2],[3,2,1]])
-        [1, 2, 3]
-    """
-
-    if len(l) == 0:
-        return None
-    new_l = l[:]
-    new_l.sort(cmp=lex_cmp)
-    return new_l[0]
-
-
-###################
-# Shuffle Product #
-###################
-
-
-## def shuffle(w1,w2):
-##     """
-##     Returns the list of words in the shuffle product
-##     of w1 and w2.
-
-##     """
-##     return shuffle_list(w1,w2)
-
-## def shuffle_shifted(w1, w2):
-##     """
-##     Returns the shifted shuffle of w1 and w2.
-
-##     EXAMPLES:
-
-##     """
-
-##     return shuffle(w1, [x+len(w1) for x in v])
-
-## def shuffle_count(w1,w2):
-##     """
-##     Returns the number of words in the shuffle product
-##     of w1 and w2.
-
-##     It is given by binomial(len(w1)+len(w2), len(w1)).
-
-##     EXAMPLES:
-##         sage: word.shuffle_count([2,3],[3,4])
-##         6
-##     """
-
-##     return binomial(len(w1)+len(w2), len(w1))
-    
-
-## def shuffle_list(w1,w2):
-##     """
-##     Returns the list of words in the shuffle product
-##     of w1 and w2.
-
-##     """
-
-##     return [w for w in shuffle_iterator(w1,w2)]
-
-## def shuffle_iterator(w1,w2):
-##     """
-##     Returns an iterator for the words in the
-##     shuffle product of w1 and w2.
-
-##     EXAMPLES:
-    
-##     """
-
-##     n1 = len(w1)
-##     n2 = len(w2)
-
-##     def proc(vect):
-##         i1 = -1
-##         i2 = -1
-##         res = []
-##         for v in vect:
-##             if v == 1:
-##                 i1 += 1
-##                 res.append(w1[i1])
-##             else:
-##                 i2 += 1
-##                 res.append(w2[i2])
-
-##     return itertools.imap(proc, integer_vector.iterator(n1, n1+n2, max_parts=1))
-
Index: sage/dsage/misc/hostinfo.py
===================================================================
--- sage/dsage/misc/hostinfo.py	(revision 6454)
+++ sage/dsage/misc/hostinfo.py	(revision 5740)
@@ -21,5 +21,5 @@
 import os
 from twisted.spread import pb
-from twisted.internet import     utils, defer
+from twisted.internet import reactor, utils, defer
 from twisted.python import log
 
@@ -164,5 +164,5 @@
     
     def __init__(self):
-        self.host_info = self.get_host_info()
+        self.host_info = self.get_host_info(sys.platform)
 
     def __str__(self):
@@ -172,13 +172,8 @@
         return str(self.host_info)
 
-    def get_host_info(self):
-        import platform
+    def get_host_info(self, platform):
         host_info = {}
-        #  uname = (system,node,release,version,machine,processor)
-        uname = platform.uname() 
-        host_info['os'] = uname[0]
-        
-        if host_info['os'] == 'Linux':
-            # Get CPU related data
+        host_info['os'] = platform
+        if platform in ('linux', 'linux2', 'cygwin'):
             cpuinfo = open('/proc/cpuinfo','r').readlines()
             cpus = 0
@@ -188,36 +183,40 @@
                 s = line.split(':')
                 if s != ['\n']:
-                    key = s[0].strip()
-                    value = s[1].strip()
-                    if key == 'cpu MHz':
-                        host_info[key] = int(float(value))
+                    if s[0].strip() == 'cpu MHz':
+                        host_info[s[0].strip()] = int(float(s[1].strip()))
                     else:
-                        host_info[key] = value
+                        host_info[s[0].strip()] = s[1].strip()
             host_info['cpus'] = cpus
-        
-            # perform architecture specific modifications of host_info
-            if uname[5] == 'ppc':
-                host_info['clock'] = host_info['clock'].replace('MHz', '')
-                host_info['cpu MHz'] = int(float(host_info['clock'])) 
-                host_info['model name'] = host_info['cpu']
-            elif uname[5] == 'ia64':
-                host_info['model name'] = host_info['family']
-
-            # Get memory related date
+            
+            # On Itanium /proc/cpuinfo does not have a 'model name' entry
+            # 'family' works almost as well
+            if not host_info.has_key('model name'):
+                try:
+                    host_info['model name'] = host_info['family']
+                except KeyError:
+                    host_info['model name'] = 'Unknown'
+    
+            uptime = open('/proc/uptime', 'r').readline().split(' ')
+            host_info['uptime'] = int(float(uptime[0]))
+
             meminfo = open('/proc/meminfo', 'r').readlines()
             for line in meminfo:
                 s = line.split(':')
                 if s != ['\n']:
-                    key = s[0].strip()
-                    value = s[1]
-                    if key == 'MemTotal':
-                        mem_total = int(int(value.split()[0].strip()) / 1024)
-                        host_info[key] = mem_total
-                    elif key == 'MemFree':
-                        mem_free = int(int(value.split()[0].strip()) / 1024)
-                        host_info[key] = mem_free
+                    if s[0].strip() == 'MemTotal':
+                        mem_total = int(int(s[1].split()[0].strip()) / 1024)
+                        host_info[s[0].strip()] = mem_total
+                    elif s[0].strip() == 'MemFree':
+                        mem_free = int(int(s[1].split()[0].strip()) / 1024)
+                        host_info[s[0].strip()] = mem_free
                     else:
-                        host_info[key] = value.strip()
-        elif host_info['os'] == 'Darwin':
+                        host_info[s[0].strip()] = s[1].strip()
+
+            hostname = os.popen('hostname').readline().strip()
+            host_info['hostname'] = hostname
+
+            kernel_version = os.popen('uname -r').readline().strip()
+            host_info['kernel_version'] = kernel_version
+        if platform == 'darwin':
             for line in os.popen('sysctl -a hw machdep').readlines():
                 l = line.strip()
@@ -243,11 +242,15 @@
                 elif l[0] == 'hw.model': # OS X PPC 
                     host_info['model name'] = l[1]
-
-        host_info['hostname'] = os.uname()[1]
-        host_info['kernel_version'] = os.uname()[2]
-        host_info['uptime'] = uptime = os.popen('uptime').readline().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
+
         return self.canonical_info(host_info)
-        
+
     def canonical_info(self, platform_host_info):
         """
@@ -266,6 +269,5 @@
                       'cpus': 'cpus',
                       'ip': 'ip',
-                      'os': 'os',
-                      'uptime': 'uptime'}
+                      'os': 'os'}
         canonical_info = {}
         for k,v in platform_host_info.iteritems():
Index: sage/graphs/graph.py
===================================================================
--- sage/graphs/graph.py	(revision 6440)
+++ sage/graphs/graph.py	(revision 6468)
@@ -470,4 +470,31 @@
         n = (n**2 - n)/2
         return Rational(self.size())/Rational(n)
+
+    def to_simple(self):
+        """
+        Returns a simple version of itself (i.e., undirected and loops
+        and multiple edges are removed).
+
+        EXAMPLE:
+            sage: G = DiGraph(loops=True,multiedges=True)
+            sage: G.add_arcs( [ (0,0), (1,1), (2,2), (2,3), (2,3), (3,2) ] )
+            sage: G.arcs(labels=False)
+            [(0, 0), (1, 1), (2, 2), (2, 3), (2, 3), (3,2)]
+            sage: H=G.to_simple()
+            sage: H.edges(labels=False)
+            [(2, 3)]
+            sage: H.is_undirected()
+            True
+            sage: H.loops()
+            False
+            sage: H.multiple_edges()
+            False
+        
+        """
+        g=self.to_undirected()
+        g.loops(False)
+        g.multiple_edges(False)
+        return g
+
 
     def order(self):
@@ -2575,8 +2602,8 @@
             elif isinstance(data, Graph):
                 self._nxg = data.networkx_graph()
+            elif isinstance(data, networkx.XGraph):
+                self._nxg = data
             elif isinstance(data, networkx.Graph):
                 self._nxg = networkx.XGraph(data, selfloops=loops, **kwds)
-            elif isinstance(data, networkx.XGraph):
-                self._nxg = data
             else:
                 self._nxg = networkx.XGraph(data, selfloops=loops, **kwds)
@@ -2739,6 +2766,12 @@
         Creates a copy of the graph.
 
-        """
-        G = Graph(self._nxg, name=self._nxg.name, pos=self._pos, loops=self.loops(), boundary=self._boundary)
+        EXAMPLE:
+            sage: g=Graph({0:[0,1,1,2]},loops=True,multiedges=True)
+            sage: g==g.copy()
+            True
+
+
+        """
+        G = Graph(self._nxg, name=self._nxg.name, pos=self._pos, boundary=self._boundary)
         return G
 
@@ -2753,6 +2786,5 @@
 
         """
-        return DiGraph(self._nxg.to_directed(), pos=self._pos)
-
+        return DiGraph(self._nxg.to_directed(), name=self._nxg.name, pos=self._pos, boundary=self._boundary)
     def to_undirected(self):
         """
@@ -3579,5 +3611,5 @@
             raise TypeError("Graph must be connected to use Euler's Formula to compute minimal genus.")
         from sage.rings.infinity import Infinity
-        from sage.combinat.all import CyclicPermutationsOfPartition
+        from sage.combinat.combinat import cyclic_permutations_of_partition_iterator
         from sage.graphs.graph_genus1 import trace_faces, nice_copy
 
@@ -3605,5 +3637,5 @@
 
         all_perms = []
-        for p in CyclicPermutationsOfPartition(part):
+        for p in cyclic_permutations_of_partition_iterator(part):
             if ordered:
                 p.append(boundary)
@@ -3644,5 +3676,5 @@
             raise TypeError("Graph must be connected to use Euler's Formula to compute minimal genus.")
         from sage.rings.infinity import Infinity
-        from sage.combinat.all import CyclicPermutationsOfPartition
+        from sage.combinat.combinat import cyclic_permutations_of_partition_iterator
         from sage.graphs.graph_genus1 import trace_faces, nice_copy
 
@@ -3658,5 +3690,5 @@
 
         all_perms = []
-        for p in CyclicPermutationsOfPartition(part):
+        for p in cyclic_permutations_of_partition_iterator(part):
             all_perms.append(p)
 
@@ -4286,10 +4318,10 @@
                 return a
     
-    def is_isomorphic(self, other, certify=False, verbosity=0):
+    def is_isomorphic(self, other, proof=False, verbosity=0):
         """
         Tests for isomorphism between self and other.
         
         INPUT:
-            certify -- if True, then output is (a,b), where a is a boolean and b is either a map or
+            proof -- if True, then output is (a,b), where a is a boolean and b is either a map or
         None.
         
@@ -4308,5 +4340,5 @@
             sage: E = D.copy()
             sage: E.relabel(gamma)
-            sage: a,b = D.is_isomorphic(E, certify=True); a
+            sage: a,b = D.is_isomorphic(E, proof=True); a
             True
             sage: import networkx
@@ -4322,5 +4354,5 @@
             raise NotImplementedError, "Search algorithm does not support multiple edges yet."
         from sage.graphs.graph_isom import search_tree
-        if certify:
+        if proof:
             if self.order() != other.order():
                 return False, None
@@ -4329,6 +4361,6 @@
             if sorted(list(self.degree_iterator())) != sorted(list(other.degree_iterator())):
                 return False, None
-            b,a = self.canonical_label(certify=True, verbosity=verbosity)
-            d,c = other.canonical_label(certify=True, verbosity=verbosity)
+            b,a = self.canonical_label(proof=True, verbosity=verbosity)
+            d,c = other.canonical_label(proof=True, verbosity=verbosity)
             map = {}
             cc = c.items()
@@ -4354,5 +4386,5 @@
             return enum(b) == enum(d)
     
-    def canonical_label(self, partition=None, certify=False, verbosity=0):
+    def canonical_label(self, partition=None, proof=False, verbosity=0):
         """
         Returns the canonical label with respect to the partition. If no
@@ -4363,5 +4395,5 @@
             sage: E = D.canonical_label(); E
             Dodecahedron: Graph on 20 vertices
-            sage: D.canonical_label(certify=True)
+            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})
             sage: D.is_isomorphic(E)
@@ -4374,6 +4406,6 @@
         if partition is None:
             partition = [self.vertices()]
-        if certify:
-            a,b,c = search_tree(self, partition, certify=True, dig=self.loops(), verbosity=verbosity)
+        if proof:
+            a,b,c = search_tree(self, partition, proof=True, dig=self.loops(), verbosity=verbosity)
             return b,c
         else:
@@ -4480,8 +4512,8 @@
             elif isinstance(data, DiGraph):
                 self._nxg = data.networkx_graph()
+            elif isinstance(data, networkx.XDiGraph):
+                self._nxg = data
             elif isinstance(data, networkx.DiGraph):
                 self._nxg = networkx.XDiGraph(data, selfloops=loops, **kwds)
-            elif isinstance(data, networkx.XDiGraph):
-                self._nxg = data
             elif isinstance(data, str):
                 format = 'dig6'
@@ -4584,6 +4616,11 @@
         Creates a copy of the graph.
 
-        """
-        G = DiGraph(self._nxg, name=self._nxg.name, pos=self._pos, loops=self.loops(), boundary=self._boundary)
+        EXAMPLE:
+            sage: g=DiGraph({0:[0,1,1,2],1:[0,1]},loops=True,multiedges=True)
+            sage: g==g.copy()
+            True
+
+        """
+        G = DiGraph(self._nxg, name=self._nxg.name, pos=self._pos, boundary=self._boundary)
         return G
 
@@ -4612,5 +4649,5 @@
 
         """
-        return Graph(self._nxg.to_undirected(), pos=self._pos)
+        return Graph(self._nxg.to_undirected(), name=self._nxg.name, pos=self._pos, boundary=self._boundary)
 
     ### General Properties
@@ -5630,10 +5667,10 @@
                 return a
     
-    def is_isomorphic(self, other, certify=False, verbosity=0):
+    def is_isomorphic(self, other, proof=False, verbosity=0):
         """
         Tests for isomorphism between self and other.
         
         INPUT:
-            certify -- if True, then output is (a,b), where a is a boolean and b is either a map or
+            proof -- if True, then output is (a,b), where a is a boolean and b is either a map or
         None.
         
@@ -5641,5 +5678,5 @@
             sage: A = DiGraph( { 0 : [1,2] } )
             sage: B = DiGraph( { 1 : [0,2] } )
-            sage: A.is_isomorphic(B, certify=True)
+            sage: A.is_isomorphic(B, proof=True)
             (True, {0: 1, 1: 0, 2: 2})
 
@@ -5648,5 +5685,5 @@
             raise NotImplementedError, "Search algorithm does not support multiple edges yet."
         from sage.graphs.graph_isom import search_tree
-        if certify:
+        if proof:
             if self.order() != other.order():
                 return False, None
@@ -5657,6 +5694,6 @@
             if sorted(list(self.out_degree_iterator())) != sorted(list(other.out_degree_iterator())):
                 return False, None
-            b,a = self.canonical_label(certify=True, verbosity=verbosity)
-            d,c = other.canonical_label(certify=True, verbosity=verbosity)
+            b,a = self.canonical_label(proof=True, verbosity=verbosity)
+            d,c = other.canonical_label(proof=True, verbosity=verbosity)
             if enum(b) == enum(d):
                 map = {}
@@ -5684,5 +5721,5 @@
             return enum(b) == enum(d)
     
-    def canonical_label(self, partition=None, certify=False, verbosity=0):
+    def canonical_label(self, partition=None, proof=False, verbosity=0):
         """
         Returns the canonical label with respect to the partition. If no
@@ -5711,6 +5748,6 @@
         if partition is None:
             partition = [self.vertices()]
-        if certify:
-            a,b,c = search_tree(self, partition, certify=True, dig=True, verbosity=verbosity)
+        if proof:
+            a,b,c = search_tree(self, partition, proof=True, dig=True, verbosity=verbosity)
             return b,c
         else:
Index: sage/graphs/graph_genus1.py
===================================================================
--- sage/graphs/graph_genus1.py	(revision 6439)
+++ sage/graphs/graph_genus1.py	(revision 5445)
@@ -182,5 +182,5 @@
             (3, 1)]])]
     """
-    from sage.combinat.all import CyclicPermutationsOfPartition
+    from sage.combinat.combinat import cyclic_permutations_of_partition_iterator
 
     graph = nice_copy(graph)
@@ -194,5 +194,5 @@
         part.append(graph.neighbors(node))
     all_perms = []
-    for p in CyclicPermutationsOfPartition(part):
+    for p in cyclic_permutations_of_partition_iterator(part):
         all_perms.append(p)
 
@@ -279,5 +279,5 @@
            [(5, 4), (4, 3), (3, 2), (2, 1), (1, 0), (0, 8), (8, 7), (7, 6), (6, 5)]])]
     """
-    from sage.combinat.all import CyclicPermutationsOfPartition
+    from sage.combinat.combinat import cyclic_permutations_of_partition_iterator
 
     graph = nice_copy(graph)
@@ -291,5 +291,5 @@
         part.append(graph.neighbors(node))
     all_perms = []
-    for p in CyclicPermutationsOfPartition(part):
+    for p in cyclic_permutations_of_partition_iterator(part):
         all_perms.append(p)
 
Index: sage/graphs/graph_isom.pyx
===================================================================
--- sage/graphs/graph_isom.pyx	(revision 6409)
+++ sage/graphs/graph_isom.pyx	(revision 5445)
@@ -762,5 +762,5 @@
     return H
 
-def search_tree(G, Pi, lab=True, dig=False, dict=False, certify=False, verbosity=0):
+def search_tree(G, Pi, lab=True, dig=False, dict=False, proof=False, verbosity=0):
     """
     Assumes that the vertex set of G is {0,1,...,n-1} for some n.
@@ -777,5 +777,5 @@
         dict--      if True, explain which vertices are which elements of the set
     {1,2,...,n} in the representation of the automorphism group.
-        certify--     if True, return the automorphism between G and its canonical
+        proof--     if True, return the automorphism between G and its canonical
     label. Forces lab=True.
         verbosity-- 0 - print nothing
@@ -889,5 +889,5 @@
         
         sage: D = graphs.DodecahedralGraph()
-        sage: a,b,c = search_tree(D, [range(20)], certify=True)
+        sage: a,b,c = search_tree(D, [range(20)], proof=True)
         sage: from sage.plot.plot import GraphicsArray # long time
         sage: import networkx # long time
@@ -1208,5 +1208,5 @@
         if dict:
             ddd = {}
-        if certify:
+        if proof:
             dd = {}
             if dict:
@@ -1223,5 +1223,5 @@
             return [[]]        
     
-    if certify:
+    if proof:
         lab=True
 
@@ -1761,5 +1761,5 @@
                 ddd[v] = n
 
-    if certify:
+    if proof:
         dd = {}
         for i from 0 <= i < n:
Index: sage/groups/abelian_gps/abelian_group.py
===================================================================
--- sage/groups/abelian_gps/abelian_group.py	(revision 6439)
+++ sage/groups/abelian_gps/abelian_group.py	(revision 3352)
@@ -319,5 +319,5 @@
         Multiplicative Abelian Group isomorphic to C5 x C5 x C7 x C8 x C9
         sage: F = AbelianGroup(5,[2, 4, 12, 24, 120],names = list("abcde")); F
-        Multiplicative Abelian Group isomorphic to C2 x C4 x C12 x C24 x C120
+        Multiplicative Abelian Group isomorphic to C2 x C3 x C3 x C3 x C4 x C4 x C5 x C8 x C8
         sage: F.elementary_divisors()
         [2, 3, 3, 3, 4, 4, 5, 8, 8]
@@ -350,4 +350,5 @@
             if 1 in invs:
                 invs.remove(1) 
+        invs.sort()
         self.__invariants = invs
         # *now* define ngens
@@ -364,5 +365,5 @@
             sage: G = AbelianGroup(2,[2,6])
             sage: G
-            Multiplicative Abelian Group isomorphic to C2 x C6
+            Multiplicative Abelian Group isomorphic to C2 x C2 x C3
             sage: G.invariants()
             [2, 6]
@@ -444,11 +445,7 @@
 
     def _repr_(self):
-        eldv = self.invariants()
-        if len(eldv) == 0:
+        eldv = self.elementary_divisors()
+        if eldv == []:
             return "Trivial Abelian Group"
-        g = self._group_notation(eldv)
-        return "Multiplicative Abelian Group isomorphic to " + g
-
-    def _group_notation(self, eldv):
         v = []
         for x in eldv:
@@ -457,5 +454,7 @@
             else:
                 v.append("Z")
-        return ' x '.join(v)
+        gp = ' x '.join(v)
+        s = "Multiplicative Abelian Group isomorphic to "+gp
+        return s
 
     def _latex_(self):
@@ -661,12 +660,11 @@
             sage: a,b,c,d,e = F.gens()
             sage: F.subgroup([a,b])
-            Multiplicative Abelian Group isomorphic to Z x Z, which is
-            the subgroup of Multiplicative Abelian Group isomorphic to
-            Z x Z x C30 x C64 x C729 generated by [a, b]
+            Multiplicative Abelian Group isomorphic to Z x Z, which is the subgroup of
+            Multiplicative Abelian Group isomorphic to Z x Z x C2 x C3 x C5 x C64 x C729
+            generated by [a, b]
             sage: F.subgroup([c,e])
-            Multiplicative Abelian Group isomorphic to C2 x C3 x C5 x
-            C729, which is the subgroup of Multiplicative Abelian
-            Group isomorphic to Z x Z x C30 x C64 x C729 generated by
-            [c, e]
+            Multiplicative Abelian Group isomorphic to C2 x C3 x C5 x C729, which is the subgroup of
+            Multiplicative Abelian Group isomorphic to Z x Z x C2 x C3 x C5 x C64 x C729
+            generated by [c, e]
          """
         if not isinstance(gensH, (list, tuple)):
@@ -714,4 +712,5 @@
             [1, b, b^2, a, a*b, a*b^2]
         """
+        from sage.combinat.combinat import tuples
         if not(self.is_finite()):
            raise NotImplementedError, "Group must be finite"
@@ -761,44 +760,35 @@
             sage: F.subgroup([a^3,b])
             Multiplicative Abelian Group isomorphic to Z x Z, which is the subgroup of
-            Multiplicative Abelian Group isomorphic to Z x Z x C30 x C64 x C729
-            generated by [a^3, b]            
-
+            Multiplicative Abelian Group isomorphic to Z x Z x C2 x C3 x C5 x C64 x C729
+            generated by [a^3, b]
             sage: F.subgroup([c])
             Multiplicative Abelian Group isomorphic to C2 x C3 x C5, which is the subgroup of
-            Multiplicative Abelian Group isomorphic to Z x Z x C30 x C64 x C729
+            Multiplicative Abelian Group isomorphic to Z x Z x C2 x C3 x C5 x C64 x C729
             generated by [c]
-
             sage: F.subgroup([a,c])
-            Multiplicative Abelian Group isomorphic to C2 x C3 x C5 x
-            Z, which is the subgroup of Multiplicative Abelian Group
-            isomorphic to Z x Z x C30 x C64 x C729 generated by [a, c]
-            
+            Multiplicative Abelian Group isomorphic to Z x C2 x C3 x C5, which is the subgroup of
+            Multiplicative Abelian Group isomorphic to Z x Z x C2 x C3 x C5 x C64 x C729
+            generated by [a, c]
             sage: F.subgroup([a,b*c])
-            Multiplicative Abelian Group isomorphic to Z x Z, which is
-            the subgroup of Multiplicative Abelian Group isomorphic to
-            Z x Z x C30 x C64 x C729 generated by [a, b*c]
-
+            Multiplicative Abelian Group isomorphic to Z x Z, which is the subgroup of
+            Multiplicative Abelian Group isomorphic to Z x Z x C2 x C3 x C5 x C64 x C729
+            generated by [a, b*c]
             sage: F.subgroup([b*c,d])
-            Multiplicative Abelian Group isomorphic to C64 x Z, which
-            is the subgroup of Multiplicative Abelian Group isomorphic
-            to Z x Z x C30 x C64 x C729 generated by [b*c, d]
-
+            Multiplicative Abelian Group isomorphic to Z x C64, which is the subgroup of
+            Multiplicative Abelian Group isomorphic to Z x Z x C2 x C3 x C5 x C64 x C729
+            generated by [b*c, d]
             sage: F.subgroup([a*b,c^6,d],names = list("xyz"))
-            Multiplicative Abelian Group isomorphic to C5 x C64 x Z,
-            which is the subgroup of Multiplicative Abelian Group
-            isomorphic to Z x Z x C30 x C64 x C729 generated by [a*b,
-            c^6, d]
-
+            Multiplicative Abelian Group isomorphic to Z x C5 x C64, which is the subgroup of
+            Multiplicative Abelian Group isomorphic to Z x Z x C2 x C3 x C5 x C64 x C729
+            generated by [a*b, c^6, d]
             sage: H.<x,y,z> = F.subgroup([a*b, c^6, d]); H
-            Multiplicative Abelian Group isomorphic to C5 x C64 x Z,
-            which is the subgroup of Multiplicative Abelian Group
-            isomorphic to Z x Z x C30 x C64 x C729 generated by [a*b,
-            c^6, d]
-
-            sage: G = F.subgroup([a*b,c^6,d],names = list("xyz")); G
-            Multiplicative Abelian Group isomorphic to C5 x C64 x Z,
-            which is the subgroup of Multiplicative Abelian Group
-            isomorphic to Z x Z x C30 x C64 x C729 generated by [a*b,
-            c^6, d]
+            Multiplicative Abelian Group isomorphic to Z x C5 x C64, which is the subgroup of
+            Multiplicative Abelian Group isomorphic to Z x Z x C2 x C3 x C5 x C64 x C729
+            generated by [a*b, c^6, d]
+            sage: G = F.subgroup([a*b,c^6,d],names = list("xyz"))
+            sage: G
+            Multiplicative Abelian Group isomorphic to Z x C5 x C64, which is the subgroup of
+            Multiplicative Abelian Group isomorphic to Z x Z x C2 x C3 x C5 x C64 x C729
+            generated by [a*b, c^6, d]
             sage: x,y,z = G.gens()
             sage: x.order()
@@ -839,9 +829,9 @@
             sage: A = AbelianGroup(4,[1008, 2003, 3001, 4001], names = "abcd")
             sage: a,b,c,d = A.gens()
-            sage: B = A.subgroup([a^3,b,c,d]); B
-            Multiplicative Abelian Group isomorphic to C3 x C7 x C16 x
-            C2003 x C3001 x C4001, which is the subgroup of
-            Multiplicative Abelian Group isomorphic to C1008 x C2003 x
-            C3001 x C4001 generated by [a^3, b, c, d]
+            sage: B = A.subgroup([a^3,b,c,d])
+            sage: B
+            Multiplicative Abelian Group isomorphic to C3 x C7 x C16 x C2003 x C3001 x C4001, which is the subgroup of
+            Multiplicative Abelian Group isomorphic to C7 x C9 x C16 x C2003 x C3001 x C4001
+            generated by [a^3, b, c, d]
              
         Infinite groups can also be handled:
@@ -849,10 +839,9 @@
             sage: a,b,c = G.gens()
             sage: F = G.subgroup([a,b^2,c]); F
-            Multiplicative Abelian Group isomorphic to C2 x C3 x Z,
-            which is the subgroup of Multiplicative Abelian Group
-            isomorphic to C3 x C4 x Z generated by [a, b^2, c]
-
+            Multiplicative Abelian Group isomorphic to Z x C3 x C4, which is the subgroup of
+            Multiplicative Abelian Group isomorphic to Z x C3 x C4
+            generated by [a, b^2, c]
             sage: F.invariants()
-            [2, 3, 0]
+            [0, 3, 4]
             sage: F.gens()
             [a, b^2, c]
Index: sage/groups/abelian_gps/dual_abelian_group.py
===================================================================
--- sage/groups/abelian_gps/dual_abelian_group.py	(revision 6439)
+++ sage/groups/abelian_gps/dual_abelian_group.py	(revision 3311)
@@ -345,4 +345,5 @@
             
         """
+        from sage.combinat.combinat import tuples
         if not(self.is_finite()):
            raise NotImplementedError, "Group must be finite"
Index: sage/interfaces/expect.py
===================================================================
--- sage/interfaces/expect.py	(revision 6407)
+++ sage/interfaces/expect.py	(revision 6154)
@@ -37,6 +37,4 @@
 ########################################################
 import pexpect
-from pexpect import ExceptionPexpect
-
 
 from sage.structure.sage_object import SageObject
@@ -387,5 +385,5 @@
                 cleaner.cleaner(self._expect.pid, cmd)
             
-        except (ExceptionPexpect, pexpect.EOF, IndexError):
+        except (pexpect.ExceptionPexpect, pexpect.EOF, IndexError):
             self._expect = None
             self._session_number = BAD_SESSION
@@ -601,6 +599,7 @@
             try:
                 self._expect.close(force=1)
-            except pexpect.ExceptionPexpect, msg:
-                raise pexcept.ExceptionPexpect( "THIS IS A BUG -- PLEASE REPORT. This should never happen.\n" + msg)
+            except pexpect.ExceptionPexpect:
+                print "WARNING: -- unable to kill %s. You may have to do so manually."%self
+                pass
             self._start()
             raise KeyboardInterrupt, "Restarting %s (WARNING: all variables defined in previous session are now invalid)"%self
@@ -1001,5 +1000,5 @@
                     P.clear(self._name)
                 
-        except (RuntimeError, ExceptionPexpect), msg:    # needed to avoid infinite loops in some rare cases
+        except (RuntimeError, pexpect.ExceptionPexpect), msg:    # needed to avoid infinite loops in some rare cases
             #print msg
             pass
Index: sage/interfaces/gap.py
===================================================================
--- sage/interfaces/gap.py	(revision 6348)
+++ sage/interfaces/gap.py	(revision 5878)
@@ -157,4 +157,7 @@
 first_try = True
 
+if not os.path.exists('%s/tmp'%SAGE_ROOT):
+    os.makedirs('%s/tmp'%SAGE_ROOT)
+    
 if not os.path.exists('%s/gap/'%DOT_SAGE):
     os.makedirs('%s/gap/'%DOT_SAGE)
Index: sage/interfaces/maxima.py
===================================================================
--- sage/interfaces/maxima.py	(revision 6406)
+++ sage/interfaces/maxima.py	(revision 6072)
@@ -349,6 +349,5 @@
 from pexpect import EOF
 
-#import random
-from random import randrange
+import random
 
 import sage.rings.all
@@ -590,5 +589,5 @@
         """
         if self._expect is None: return
-        r = randrange(2147483647)
+        r = random.randrange(2147483647)
         s = str(r+1)
         cmd = "1+%s;\n"%r
Index: sage/interfaces/singular.py
===================================================================
--- sage/interfaces/singular.py	(revision 6407)
+++ sage/interfaces/singular.py	(revision 5932)
@@ -741,13 +741,4 @@
             SingularFunction(self,"option")("\""+str(cmd)+"\"")
 
-    def _keyboard_interrupt(self):
-        print "Interrupting %s..."%self
-        try:
-            self._expect.sendline(chr(4))
-        except pexpect.ExceptionPexpect, msg:
-            raise pexcept.ExceptionPexpect("THIS IS A BUG -- PLEASE REPORT. This should never happen.\n" + msg)
-        self._start()
-        raise KeyboardInterrupt, "Restarting %s (WARNING: all variables defined in previous session are now invalid)"%self
-
 class SingularElement(ExpectElement):
     def __init__(self, parent, type, value, is_name=False):
Index: sage/libs/all.py
===================================================================
--- sage/libs/all.py	(revision 6440)
+++ sage/libs/all.py	(revision 5211)
@@ -15,3 +15,2 @@
 
 
-import symmetrica.all as symmetrica
Index: age/libs/flint/flint.pxi
===================================================================
--- sage/libs/flint/flint.pxi	(revision 6353)
+++ 	(revision )
@@ -1,2 +1,0 @@
-cdef extern from "flint.h":
-    pass
Index: age/libs/flint/fmpz_poly.pxd
===================================================================
--- sage/libs/flint/fmpz_poly.pxd	(revision 6353)
+++ 	(revision )
@@ -1,10 +1,0 @@
-include "../../ext/stdsage.pxi"
-include "../../ext/cdefs.pxi"
-
-include "flint.pxi"
-include "fmpz_poly.pxi"
-
-from sage.structure.sage_object cimport SageObject
-
-cdef class Fmpz_poly(SageObject):
-    cdef fmpz_poly_t poly
Index: age/libs/flint/fmpz_poly.pxi
===================================================================
--- sage/libs/flint/fmpz_poly.pxi	(revision 6353)
+++ 	(revision )
@@ -1,49 +1,0 @@
-cdef extern from "FLINT/fmpz_poly.h":
-    
-    ctypedef void* fmpz_poly_t
-    
-    void fmpz_poly_init(fmpz_poly_t poly)
-    void fmpz_poly_init2(fmpz_poly_t poly, unsigned long alloc, unsigned long limbs)
-    void fmpz_poly_realloc(fmpz_poly_t poly, unsigned long alloc)
-    
-    void fmpz_poly_fit_length(fmpz_poly_t poly, unsigned long alloc)
-    void fmpz_poly_resize_limbs(fmpz_poly_t poly, unsigned long limbs)
-    void fmpz_poly_fit_limbs(fmpz_poly_t poly, unsigned long limbs)
-
-    void fmpz_poly_clear(fmpz_poly_t poly)
-    
-    long fmpz_poly_degree(fmpz_poly_t poly)
-    unsigned long fmpz_poly_length(fmpz_poly_t poly)
-
-    
-    void fmpz_poly_set_length(fmpz_poly_t poly, unsigned long length)
-    void fmpz_poly_truncate(fmpz_poly_t poly, unsigned long length)
-    
-    void fmpz_poly_set_coeff_si(fmpz_poly_t poly, unsigned long n, long x)
-    void fmpz_poly_set_coeff_ui(fmpz_poly_t poly, unsigned long n, unsigned long x)
-    
-    void fmpz_poly_get_coeff_mpz(mpz_t x, fmpz_poly_t poly, unsigned long n)
-    
-    void fmpz_poly_mul(fmpz_poly_t output, fmpz_poly_t input1, fmpz_poly_t input2)
-    void fmpz_poly_mul_trunc_n(fmpz_poly_t output, fmpz_poly_t input1, fmpz_poly_t input2, unsigned long trunc)
-    void fmpz_poly_mul_trunc_left_n(fmpz_poly_t output, fmpz_poly_t input1, fmpz_poly_t input2, unsigned long trunc)
-
-    void fmpz_poly_div_naive(fmpz_poly_t Q, fmpz_poly_t A, fmpz_poly_t B)
-    
-    bint fmpz_poly_from_string(fmpz_poly_t poly, char* s)
-    char* fmpz_poly_to_string(fmpz_poly_t poly)
-    void fmpz_poly_print(fmpz_poly_t poly)
-    bint fmpz_poly_read(fmpz_poly_t poly)
-
-    void fmpz_poly_divrem_naive(fmpz_poly_t Q, fmpz_poly_t R, fmpz_poly_t A, fmpz_poly_t B)
-    void fmpz_poly_div_karatsuba_recursive(fmpz_poly_t Q, fmpz_poly_t DQ, fmpz_poly_t A, fmpz_poly_t B)
-    void fmpz_poly_divrem_karatsuba(fmpz_poly_t Q, fmpz_poly_t R, fmpz_poly_t A, fmpz_poly_t B)
-    void fmpz_poly_div_karatsuba(fmpz_poly_t Q, fmpz_poly_t A, fmpz_poly_t B)
-    void fmpz_poly_newton_invert_basecase(fmpz_poly_t Q_inv, fmpz_poly_t Q, unsigned long n)
-    void fmpz_poly_newton_invert(fmpz_poly_t Q_inv, fmpz_poly_t Q, unsigned long n)
-    void fmpz_poly_div_series(fmpz_poly_t Q, fmpz_poly_t A, fmpz_poly_t B, unsigned long n)
-    void fmpz_poly_div_newton(fmpz_poly_t Q, fmpz_poly_t A, fmpz_poly_t B)
-
-    void fmpz_poly_power(fmpz_poly_t output, fmpz_poly_t poly, unsigned long exp)
-    
-    
Index: age/libs/flint/fmpz_poly.pyx
===================================================================
--- sage/libs/flint/fmpz_poly.pyx	(revision 6353)
+++ 	(revision )
@@ -1,207 +1,0 @@
-"""
-FLINT wrapper
-
-AUTHORS: 
-   - Robert Bradshaw (2007-09-15) Initial version. 
-"""
-
-
-#*****************************************************************************
-#       Copyright (C) 2007 Robert Bradshaw <robertwb@math.washington.edu>
-#
-#  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/
-#*****************************************************************************
-
-
-include "../../ext/python_sequence.pxi"
-
-from sage.structure.sage_object cimport SageObject
-from sage.rings.integer cimport Integer
-
-cdef class Fmpz_poly(SageObject):
-    
-    def __new__(self, v=None):
-        fmpz_poly_init(self.poly)
-        
-    def __init__(self, v):
-        """
-        Construct a new fmpz_poly from a sequence, constant coefficient, 
-        or string (in the same format as it prints).
-        
-        EXAMPLES: 
-            sage: from sage.libs.flint.fmpz_poly import Fmpz_poly
-            sage: Fmpz_poly([1,2,3])
-            3  1 2 3
-            sage: Fmpz_poly(5)
-            1  5
-            sage: Fmpz_poly(str(Fmpz_poly([3,5,7])))
-            3  3 5 7
-        """
-        cdef Py_ssize_t i
-        cdef long c
-        if PY_TYPE_CHECK(v, str):
-            if fmpz_poly_from_string(self.poly, v):
-                return
-            else:
-                raise ValueError, "Unable to create Fmpz_poly from that string."
-        if not PySequence_Check(v):
-            v = [v]
-        try:
-            for i from 0 <= i < len(v):
-                fmpz_poly_set_coeff_si(self.poly, i, v[i])
-        except OverflowError:
-            raise ValueError, "No fmpz_poly_set_coeff_mpz() method."
-
-    def __dealloc__(self):
-        fmpz_poly_clear(self.poly)
-        
-    def __setitem__(self, i, value):
-        """
-        Set the $i$-th item of self, which is the coefficient of the $x^i$ term. 
-        
-        EXAMPLES: 
-            sage: from sage.libs.flint.fmpz_poly import Fmpz_poly
-            sage: f = Fmpz_poly(range(10))
-            sage: f[7] = 100; f
-            10  0 1 2 3 4 5 6 100 8 9
-        """
-        fmpz_poly_set_coeff_si(self.poly, i, value)
-          
-    def __getitem__(self, i):
-        """
-        Return the $i$-th item of self, which is the coefficient of the $x^i$ term. 
-        
-        EXAMPLES: 
-            sage: from sage.libs.flint.fmpz_poly import Fmpz_poly
-            sage: f = Fmpz_poly(range(100))
-            sage: f[13]
-            13
-            sage: f[200]
-            0
-        """
-        cdef Integer res = <Integer>PY_NEW(Integer)
-        fmpz_poly_get_coeff_mpz(res.value, self.poly, i)
-        return res
-        
-    def __repr__(self):
-        """
-        Print self according to the native FLINT format. 
-        
-        EXAMPLES: 
-            sage: from sage.libs.flint.fmpz_poly import Fmpz_poly
-            sage: f = Fmpz_poly([0,1]); f^7
-            8  0 0 0 0 0 0 0 1
-        """
-        cdef char* ss = fmpz_poly_to_string(self.poly)
-        s = ss
-        free(ss)
-        return s 
-        
-    def degree(self):
-        """
-        The degree of self.
-        
-        EXAMPLES:
-            sage: from sage.libs.flint.fmpz_poly import Fmpz_poly
-            sage: f = Fmpz_poly([1,2,3]); f
-            3  1 2 3
-            sage: f.degree()
-            2
-            sage: Fmpz_poly(range(1000)).degree()
-            999
-            sage: Fmpz_poly([2,0]).degree()
-            0
-        """
-        return fmpz_poly_degree(self.poly)
-        
-    def list(self):
-        """
-        Return self as a list of coefficients, lowest terms first. 
-        
-        EXAMPLES:
-            sage: from sage.libs.flint.fmpz_poly import Fmpz_poly
-            sage: f = Fmpz_poly([2,1,0,-1])
-            sage: f.list()
-            [2, 1, 0, -1]
-        """
-        return [self[i] for i in xrange(self.degree()+1)]
-        
-    def __add__(left, right):
-        if not PY_TYPE_CHECK(left, Fmpz_poly) or not PY_TYPE_CHECK(right, Fmpz_poly):
-            raise TypeError
-        cdef Fmpz_poly res = <Fmpz_poly>PY_NEW(Fmpz_poly)
-        raise NotImplementedError, "no fmpz_poly_add" # fmpz_poly_add(res.poly, (<Fmpz_poly>left).poly, (<Fmpz_poly>right).poly)
-        return res
-        
-    def __sub__(left, right):
-        if not PY_TYPE_CHECK(left, Fmpz_poly) or not PY_TYPE_CHECK(right, Fmpz_poly):
-            raise TypeError
-        cdef Fmpz_poly res = <Fmpz_poly>PY_NEW(Fmpz_poly)
-        raise NotImplementedError, "no fmpz_poly_sub" # fmpz_poly_sub(res.poly, (<Fmpz_poly>left).poly, (<Fmpz_poly>right).poly)
-        return res
-        
-    def __neg__(self):
-        cdef Fmpz_poly res = <Fmpz_poly>PY_NEW(Fmpz_poly)
-        raise NotImplementedError, "no _fmpz_poly_neg" #_fmpz_poly_neg(res.poly, self.poly)
-        return res
-        
-    def __mul__(left, right):
-        """
-        EXAMPLES:
-            sage: from sage.libs.flint.fmpz_poly import Fmpz_poly
-            sage: f = Fmpz_poly([0,1]); g = Fmpz_poly([2,3,4])
-            sage: f*g
-            4  0 2 3 4
-            sage: f = Fmpz_poly([1,0,-1]); g = Fmpz_poly([2,3,4])
-            sage: f*g
-            5  2 3 2 -3 -4
-        """
-        if not PY_TYPE_CHECK(left, Fmpz_poly) or not PY_TYPE_CHECK(right, Fmpz_poly):
-            raise TypeError
-        cdef Fmpz_poly res = <Fmpz_poly>PY_NEW(Fmpz_poly)
-        fmpz_poly_mul(res.poly, (<Fmpz_poly>left).poly, (<Fmpz_poly>right).poly)
-        return res
-        
-    def __pow__(self, n, dummy):
-        """
-        EXAMPLES:
-            sage: from sage.libs.flint.fmpz_poly import Fmpz_poly
-            sage: f = Fmpz_poly([1,1])
-            sage: f**6
-            7  1 6 15 20 15 6 1
-            sage: f = Fmpz_poly([2])
-            sage: f^150
-            1  1427247692705959881058285969449495136382746624
-            sage: 2^150
-            1427247692705959881058285969449495136382746624
-        """
-        cdef long nn = n
-        if not PY_TYPE_CHECK(self, Fmpz_poly):
-            raise TypeError
-        cdef Fmpz_poly res = <Fmpz_poly>PY_NEW(Fmpz_poly)
-        fmpz_poly_power(res.poly, (<Fmpz_poly>self).poly, nn)
-        return res
-        
-    def truncate(self, n):
-        """
-        EXAMPLES:
-            sage: from sage.libs.flint.fmpz_poly import Fmpz_poly
-            sage: f = Fmpz_poly([1,1])
-            sage: g = f**10; g
-            11  1 10 45 120 210 252 210 120 45 10 1
-            sage: g.truncate(5); g
-            5  1 10 45 120 210
-        """
-        cdef long nn = n
-        fmpz_poly_truncate(self.poly, nn) # mutating!
-        
-        
Index: sage/libs/linbox/linbox.pxd
===================================================================
--- sage/libs/linbox/linbox.pxd	(revision 6445)
+++ sage/libs/linbox/linbox.pxd	(revision 3506)
@@ -1,5 +1,6 @@
 include "../../ext/cdefs.pxi"
 
-include '../../modules/vector_modn_sparse_h.pxi'
+cdef extern from "../libs/m4ri/packedmatrix.h":
+    ctypedef struct packedmatrix
 
 ctypedef size_t mod_int
@@ -18,14 +19,12 @@
     cdef unsigned long rank(self) except -1
 
-cdef class Linbox_modn_sparse:
-    cdef c_vector_modint *rows
-    cdef size_t nrows
-    cdef size_t ncols
-    cdef unsigned int modulus
 
-    cdef set(self, int modulus, size_t nrows, size_t ncols, c_vector_modint *rows)
-    cdef object rank(self, int gauss)
-    cdef void solve(self, c_vector_modint **x, c_vector_modint *b, int method)
-
+## cdef class Linbox_mod2_dense:
+##     cdef packedmatrix *matrix
+    
+##     cdef set(self, packedmatrix *matrix)
+##     cdef int echelonize(self)
+##     cdef matrix_matrix_multiply(self, packedmatrix *ans, packedmatrix *B)
+##     cdef unsigned long rank(self) except -1
 
 cdef class Linbox_integer_dense:
Index: sage/libs/linbox/linbox.pyx
===================================================================
--- sage/libs/linbox/linbox.pyx	(revision 6445)
+++ sage/libs/linbox/linbox.pyx	(revision 4367)
@@ -88,46 +88,80 @@
         return r
 
+
+
+
+
+
+##########################################################################
+## Dense matrices GF(2)
+##########################################################################
+
+## cdef extern from "linbox_wrap.h":
+##     ctypedef struct packedmatrix
+
+##     cdef int linbox_mod2_dense_echelonize(packedmatrix *m)
+    
+##     cdef void linbox_mod2_dense_minpoly(mod_int **mp, size_t* degree, packedmatrix *matrix, int do_minpoly)
+    
+##     cdef int linbox_mod2_dense_matrix_matrix_multiply(packedmatrix *ans, packedmatrix *A, packedmatrix *B)
+
+##     cdef int linbox_mod2_dense_rank(packedmatrix *m)
+
+## cdef class Linbox_mod2_dense:
+##     cdef set(self, packedmatrix *matrix):
+##         self.matrix = matrix
+
+##     cdef int echelonize(self):
+##         cdef int r
+##         r = linbox_mod2_dense_echelonize(self.matrix)
+##         return r
+    
+##     def minpoly(self):
+##         return self._poly(True)
+
+##     def charpoly(self):
+##         return self._poly(False)
+
+##     def _poly(self, minpoly):
+##         """
+##         INPUT:
+##             as given
+            
+##         OUTPUT:
+##             coefficients of charpoly or minpoly as a Python list
+##         """
+##         cdef mod_int *f
+##         cdef size_t degree
+##         linbox_mod2_dense_minpoly(&f, &degree, self.matrix, minpoly)
+
+##         v = []
+##         cdef Py_ssize_t i
+##         for i from 0 <= i <= degree:
+##             v.append(f[i])
+##         linbox_modn_dense_delete_array(f)
+##         return v
+        
+##     cdef matrix_matrix_multiply(self,
+##                                 packedmatrix *ans,
+##                                 packedmatrix *B):
+##         cdef int e
+
+##         e = linbox_mod2_dense_matrix_matrix_multiply(ans, self.matrix,  B)
+##         if e:
+##             raise RuntimeError, "error doing matrix matrix multiply mod2 using linbox"
+
+##     cdef unsigned long rank(self) except -1:
+##         cdef unsigned long r
+##         r = linbox_mod2_dense_rank(self.matrix)
+##         return r
+        
+
 ##########################################################################
 ## Sparse matices modulo p.
 ##########################################################################
-
-include '../../modules/vector_modn_sparse_c.pxi'
-include '../../ext/stdsage.pxi'
-
-cdef extern from "linbox_wrap.h":
-    ctypedef struct vector_uint "std::vector<unsigned int>":
-        void (*push_back)(unsigned int)
-        int (*get "operator[]") (size_t i)
-        int (*size)()
-    
-    int linbox_modn_sparse_matrix_rank(unsigned long modulus, size_t nrows, size_t ncols, void* rows, int reorder) #, int **pivots)
-    vector_uint linbox_modn_sparse_matrix_solve(unsigned long modulus, size_t numrows, size_t numcols, void *a,  void *b, int method)
-
 cdef class Linbox_modn_sparse:
-    cdef set(self, int modulus, size_t nrows, size_t ncols, c_vector_modint *rows):
-        self.rows = rows
-        self.nrows = nrows
-        self.ncols = ncols
-        self.modulus = modulus
-
-    cdef object rank(self, int gauss):
-        #cdef int *_pivots
-        cdef int r
-        r = linbox_modn_sparse_matrix_rank(self.modulus, self.nrows, self.ncols, self.rows, gauss)
-        
-        #pivots = [_pivots[i] for i in range(r)]
-        #free(_pivots)
-        return r#, pivots
-
-    cdef void solve(self, c_vector_modint **x, c_vector_modint *b, int method):
-        """
-        """
-        cdef vector_uint X
-        X = linbox_modn_sparse_matrix_solve(self.modulus, self.nrows, self.ncols, self.rows, b, method)
-
-        for i from 0 <= i < X.size():
-            set_entry(x[0], i, X.get(i))
-            
-    
+    pass
+
+
 ##########################################################################
 ## Sparse matrices over ZZ
Index: sage/libs/ntl/all.py
===================================================================
--- sage/libs/ntl/all.py	(revision 6418)
+++ sage/libs/ntl/all.py	(revision 4818)
@@ -24,39 +24,43 @@
 #*****************************************************************************
 
-from sage.libs.ntl.ntl_ZZ import (
+from sage.libs.ntl.ntl import (make_new_ZZ as ZZ,
+                 ntl_ZZ as ZZ_class,
+                               randomBnd as ZZ_random,
+                               randomBits as ZZ_random_bits,
+                 make_new_ZZ_p as ZZ_p,
+                 ntl_ZZ_p as ZZ_p_class, \
+                 set_ZZ_p_modulus as set_modulus, \
+                 ntl_ZZ_p_random as ZZ_p_random,
+
+                 make_new_ZZX as ZZX, \
+                 ntl_ZZX as ZZX_class, \
+                 zero_ZZX, one_ZZX, \
+
                  ntl_setSeed, \
-                 ntl_ZZ as ZZ,
-                 randomBnd as ZZ_random,
-                 randomBits as ZZ_random_bits )
 
-from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext as ZZ_pContext
+                 make_new_ZZ_pX as ZZ_pX, \
+                 ntl_ZZ_pX as ZZ_pX_class, \
 
-from sage.libs.ntl.ntl_ZZ_p import (
-                 ntl_ZZ_p as ZZ_p, 
-                 set_ZZ_p_modulus as set_modulus, 
-                 ntl_ZZ_p_random as ZZ_p_random )
+                 ntl_mat_ZZ as mat_ZZ, \
 
-from sage.libs.ntl.ntl_ZZX import (
-                 ntl_ZZX as ZZX,
-                 zero_ZZX, one_ZZX )
+                 make_new_GF2X as GF2X, \
+                 ntl_GF2X as GF2X_class, \
 
-from sage.libs.ntl.ntl_ZZ_pX import ntl_ZZ_pX as ZZ_pX
-
-from sage.libs.ntl.ntl_mat_ZZ import ntl_mat_ZZ as mat_ZZ
-
-from sage.libs.ntl.ntl_GF2X import (
-                 ntl_GF2X as GF2X
-                  )
-
-
-from sage.libs.ntl.ntl_GF2E import (
-                 ntl_GF2E as GF2E, \
+                 make_new_GF2E as GF2E, \
+                 ntl_GF2E as GF2E_class, \
                  ntl_GF2E_random as GF2E_random, \
                  ntl_GF2E_modulus as GF2E_modulus, \
                  ntl_GF2E_modulus_degree as GF2E_degree, \
-                 ntl_GF2E_sage as GF2E_sage,
-                 GF2X_hex_repr as hex_output )
+                 ntl_GF2E_sage as GF2E_sage, \
+                 GF2X_hex_repr as hex_output, \
 
-from sage.libs.ntl.ntl_GF2EX import ntl_GF2EX as GF2EX
+                 make_new_GF2EX as GF2EX, \
+                 ntl_GF2EX as GF2EX_class, \
 
-from sage.libs.ntl.ntl_mat_GF2E import ntl_mat_GF2E as mat_GF2E
+
+                 ntl_mat_GF2E as mat_GF2E, \
+
+                 )
+
+mat_ZZ_class = mat_ZZ
+mat_GF2E_class = mat_GF2E
Index: sage/libs/ntl/decl.pxi
===================================================================
--- sage/libs/ntl/decl.pxi	(revision 6424)
+++ sage/libs/ntl/decl.pxi	(revision 6239)
@@ -25,6 +25,4 @@
     void ZZ_from_str "_from_str<ZZ>"(ZZ_c* dest, char* s)
 
-    void ZZ_conv_int "conv"(ZZ_c x, int i)
-    void ZZ_conv_to_long "conv"(long l, ZZ_c x)
     void conv_ZZ_int "conv"(ZZ_c x, int i)
     void add_ZZ "add"( ZZ_c x, ZZ_c a, ZZ_c b)
@@ -35,5 +33,5 @@
     void div_ZZ_ZZ "div"( ZZ_c x, ZZ_c a, ZZ_c b)
     void GCD_ZZ "GCD"(ZZ_c d, ZZ_c a, ZZ_c b)
-    void ZZ_negate "negate"(ZZ_c x, ZZ_c a)
+    void negate(ZZ_c x, ZZ_c a)
     long sign(ZZ_c d)
 #    ZZ_c *ZZ_factory "new NTL::ZZ" ()
@@ -63,17 +61,4 @@
     cdef void ZZ_set_from_int(ZZ_c* x, int value)
 
-    #### ZZ_pContext_c
-    ctypedef struct ZZ_pContext_c "struct ZZ_pContext":
-        pass
-
-    ZZ_pContext_c* ZZ_pContext_new "New<ZZ_pContext>"()
-    ZZ_pContext_c* ZZ_pContext_construct "Construct<ZZ_pContext>"(void *mem)
-    ZZ_pContext_c* ZZ_pContext_new_ZZ "ZZ_pContext_new"(ZZ_c* p)
-    ZZ_pContext_c* ZZ_pContext_construct_ZZ "ZZ_pContext_construct"(void *mem, ZZ_c* p)
-    void ZZ_pContext_destruct "Destruct<ZZ_pContext>"(ZZ_pContext_c *mem)
-    void ZZ_pContext_delete "Delete<ZZ_pContext>"(ZZ_pContext_c *mem)
-
-    void ZZ_pContext_restore(ZZ_pContext_c *c)
-
     #### ZZ_p_c
     ctypedef struct ZZ_p_c "struct ZZ_p":
@@ -81,9 +66,9 @@
 
     # Some boiler-plate
-    ZZ_p_c* ZZ_p_new "New<ZZ_p>"()
-    ZZ_p_c* ZZ_p_construct "Construct<ZZ_p>"(void *mem)
-    void ZZ_p_destruct "Destruct<ZZ_p>"(ZZ_p_c *mem)
-    void ZZ_p_delete "Delete<ZZ_p>"(ZZ_p_c *mem)
-    void ZZ_p_from_str "_from_str<ZZ_p>"(ZZ_p_c* dest, char* s)
+    ZZ_p_c* ZZ_p_new "New<ZZ_p_c>"()
+    ZZ_p_c* ZZ_p_construct "Construct<ZZ_p_c>"(void *mem)
+    void ZZ_p_destruct "Destruct<ZZ_p_c>"(ZZ_p_c *mem)
+    void ZZ_p_delete "Delete<ZZ_p_c>"(ZZ_p_c *mem)
+    void ZZ_p_from_str "_from_str<ZZ_p_c>"(ZZ_p_c* dest, char* s)
 
     ZZ_p_c* new_ZZ_p()
@@ -91,26 +76,15 @@
     void del_ZZ_p(ZZ_p_c* n)
     char* ZZ_p_to_str(ZZ_p_c* x)
-    void ZZ_p_add "add"( ZZ_p_c x, ZZ_p_c a, ZZ_p_c b)
-    void ZZ_p_sub "sub"( ZZ_p_c x, ZZ_p_c a, ZZ_p_c b)
-    void ZZ_p_mul "mul"( ZZ_p_c x, ZZ_p_c a, ZZ_p_c b)
-    void ZZ_p_mul_long "mul"( ZZ_p_c x, ZZ_p_c a, long b)
-    void ZZ_p_negate "negate"(ZZ_p_c x, ZZ_p_c a)
-    void ZZ_p_power "power"(ZZ_p_c t, ZZ_p_c x, long e)
+    ZZ_p_c* ZZ_p_add(ZZ_p_c* x, ZZ_p_c* y)
+    ZZ_p_c* ZZ_p_sub(ZZ_p_c* x, ZZ_p_c* y)
+    ZZ_p_c* ZZ_p_mul(ZZ_p_c* x, ZZ_p_c* y)
     ZZ_p_c* ZZ_p_pow(ZZ_p_c* x, long e)
     int ZZ_p_is_one(ZZ_p_c* x)
     int ZZ_p_is_zero(ZZ_p_c* x)
-    ZZ_c ZZ_p_rep "rep"(ZZ_p_c z)
     ZZ_p_c* ZZ_p_neg(ZZ_p_c* x)
     void ntl_ZZ_set_modulus(ZZ_c* x)
     int ZZ_p_eq( ZZ_p_c* x,  ZZ_p_c* y)
-    void ZZ_p_inv "inv"(ZZ_p_c r, ZZ_p_c x)
-    void ZZ_p_random "random"(ZZ_p_c r)
-    ZZ_p_c long_to_ZZ_p "to_ZZ_p"(long i)
-    ZZ_p_c ZZ_to_ZZ_p "to_ZZ_p"(ZZ_c i)
-    int ZZ_p_to_int(ZZ_p_c x)
-    ZZ_p_c int_to_ZZ_p(int i)
-    void ZZ_p_modulus(ZZ_c* mod, ZZ_p_c* x)
-    
-    ZZ_c rep(ZZ_p_c x)
+    ZZ_p_c* ZZ_p_inv(ZZ_p_c* x)
+    ZZ_p_c* ZZ_p_random()
 
     #### ZZX_c
@@ -129,6 +103,6 @@
     void PseudoRem_ZZX "PseudoRem"(ZZX_c x, ZZX_c a, ZZX_c b)
     ZZ_c LeadCoeff_ZZX "LeadCoeff"(ZZX_c x)
-    ZZ_c ZZX_coeff "coeff"(ZZX_c a, long i)
-    void ZZX_SetCoeff "SetCoeff"(ZZX_c x, long i, ZZ_c a)
+    void GetCoeff(ZZ_c x, ZZX_c a, long i)
+    void SetCoeff(ZZX_c x, long i, ZZ_c a)
     long IsZero_ZZX "IsZero"(ZZX_c a)
     # f must be monic!
@@ -140,5 +114,5 @@
     void sub_ZZX "sub"( ZZX_c x, ZZX_c a, ZZX_c b)
     void div_ZZX_ZZ "div"( ZZX_c x, ZZX_c a, ZZ_c b)
-    long ZZX_deg "deg"( ZZX_c x )
+    long deg( ZZX_c x )
     void rem_ZZX "rem"(ZZX_c r, ZZX_c a, ZZX_c b)
     void XGCD_ZZX "XGCD"(ZZ_c r, ZZX_c s, ZZX_c t, ZZX_c a, ZZX_c b, long deterministic)
@@ -205,31 +179,4 @@
         pass
 
-    ZZ_pX_c* ZZ_pX_new "New<ZZ_pX>"()
-    ZZ_pX_c* ZZ_pX_construct "Construct<ZZ_pX>"(void *mem)
-    void ZZ_pX_destruct "Destruct<ZZ_pX>"(ZZ_pX_c *mem)
-    void ZZ_pX_delete "Delete<ZZ_pX>"(ZZ_pX_c *mem)
-    void ZZ_pX_from_str "_from_str<ZZ_pX>"(ZZ_pX_c* dest, char* s)
-
-    void ZZ_pX_mul_long "mul"( ZZ_pX_c x, ZZ_pX_c a, long b)
-    void ZZ_pX_mul_ZZ "mul"( ZZ_pX_c x, ZZ_pX_c a, ZZ_c b)
-    void ZZ_pX_mul "mul"( ZZ_pX_c x, ZZ_pX_c a, ZZ_pX_c b)
-    void ZZ_pX_add "add"( ZZ_pX_c x, ZZ_pX_c a, ZZ_pX_c b)
-    void ZZ_pX_sub "sub"( ZZ_pX_c x, ZZ_pX_c a, ZZ_pX_c b)
-    void ZZ_pX_MulMod "MulMod"(ZZ_pX_c x, ZZ_pX_c a, ZZ_pX_c b, ZZ_pX_c f)
-    void ZZ_pX_div_ZZ "div"( ZZ_pX_c x, ZZ_pX_c a, ZZ_pX_c b)
-    long ZZ_pX_divide "divide"( ZZ_pX_c x, ZZ_pX_c a, ZZ_pX_c b)
-    long ZZ_pX_deg "deg"( ZZ_pX_c x )
-    void ZZ_pX_rem "rem"(ZZ_pX_c r, ZZ_pX_c a, ZZ_pX_c b)
-    void ZZ_pX_DivRem "DivRem"(ZZ_pX_c q, ZZ_pX_c r, ZZ_pX_c a, ZZ_pX_c b)
-    ZZ_p_c ZZ_pX_coeff "coeff"(ZZ_pX_c a, long i)
-    void ZZ_pX_SetCoeff "SetCoeff"(ZZ_pX_c x, long i, ZZ_p_c a)
-    void ZZ_pX_SetCoeff_long "SetCoeff"(ZZ_pX_c x, long i, long a)
-    long ZZ_pX_IsZero "IsZero"(ZZ_pX_c a)
-    void ZZ_pX_negate "negate"(ZZ_pX_c x, ZZ_pX_c a)
-    void ZZ_pX_clear "clear"(ZZ_pX_c x)
-    void ZZ_pX_GCD "GCD"(ZZ_pX_c r, ZZ_pX_c a, ZZ_pX_c b)
-    void ZZ_pX_PlainXGCD "PlainXGCD"(ZZ_pX_c d, ZZ_pX_c s, ZZ_pX_c t, ZZ_pX_c a, ZZ_pX_c b)
-    void ZZ_pX_XGCD "XGCD"(ZZ_pX_c d, ZZ_pX_c s, ZZ_pX_c t, ZZ_pX_c a, ZZ_pX_c b)
-
     ZZ_pX_c* ZZ_pX_init()
     ZZ_pX_c* str_to_ZZ_pX(char* s)
@@ -239,4 +186,8 @@
     void ZZ_pX_setitem(ZZ_pX_c* x, long i, char* a)
     char* ZZ_pX_getitem(ZZ_pX_c* x, long i)
+    ZZ_pX_c* ZZ_pX_add(ZZ_pX_c* x, ZZ_pX_c* y)
+    ZZ_pX_c* ZZ_pX_sub(ZZ_pX_c* x, ZZ_pX_c* y)
+    ZZ_pX_c* ZZ_pX_mul(ZZ_pX_c* x, ZZ_pX_c* y)
+    ZZ_pX_c* ZZ_pX_div(ZZ_pX_c* x, ZZ_pX_c* y, int* divisible)
     ZZ_pX_c* ZZ_pX_mod(ZZ_pX_c* x, ZZ_pX_c* y)
     void ZZ_pX_quo_rem(ZZ_pX_c* x, ZZ_pX_c* other, ZZ_pX_c** r, ZZ_pX_c** q)
@@ -272,4 +223,5 @@
     ZZ_pX_c* ZZ_pX_charpoly_mod(ZZ_pX_c* x, ZZ_pX_c* y)
     ZZ_pX_c* ZZ_pX_minpoly_mod(ZZ_pX_c* x, ZZ_pX_c* y)
+    void ZZ_pX_clear(ZZ_pX_c* x)
     void ZZ_pX_preallocate_space(ZZ_pX_c* x, long n)
     
@@ -282,16 +234,14 @@
 
     # Some boiler-plate
-    mat_ZZ_c* mat_ZZ_construct "Construct<mat_ZZ>"(void *mem)
-    void mat_ZZ_destruct "Destruct<mat_ZZ>"(mat_ZZ_c *mem)
-    void mat_ZZ_delete "Delete<mat_ZZ>"(mat_ZZ_c *mem)
-
-    void mat_ZZ_mul "mul"( mat_ZZ_c x, mat_ZZ_c a, mat_ZZ_c b)
-    void mat_ZZ_add "add"( mat_ZZ_c x, mat_ZZ_c a, mat_ZZ_c b)
-    void mat_ZZ_sub "sub"( mat_ZZ_c x, mat_ZZ_c a, mat_ZZ_c b)
-    void mat_ZZ_power "power"( mat_ZZ_c x, mat_ZZ_c a, long e)
-    void mat_ZZ_CharPoly "CharPoly"(ZZX_c r, mat_ZZ_c m)
-    void mat_ZZ_SetDims(mat_ZZ_c* mZZ, long nrows, long ncols)
-
+    mat_ZZ_c* mat_ZZ_construct "Construct<mat_ZZ_c>"(void *mem)
+    void mat_ZZ_destruct "Destruct<mat_ZZ_c>"(mat_ZZ_c *mem)
+    void mat_ZZ_delete "Delete<mat_ZZ_c>"(mat_ZZ_c *mem)
+
+    mat_ZZ_c* new_mat_ZZ(long nrows, long ncols)
+    void del_mat_ZZ(mat_ZZ_c* n)
     char* mat_ZZ_to_str(mat_ZZ_c* x)
+    mat_ZZ_c* mat_ZZ_add(mat_ZZ_c* x, mat_ZZ_c* y)
+    mat_ZZ_c* mat_ZZ_sub(mat_ZZ_c* x, mat_ZZ_c* y)
+    mat_ZZ_c* mat_ZZ_mul(mat_ZZ_c* x, mat_ZZ_c* y)
     mat_ZZ_c* mat_ZZ_pow(mat_ZZ_c* x, long e)
     long mat_ZZ_nrows(mat_ZZ_c* x)
@@ -309,18 +259,18 @@
         pass
 
-    GF2X_c* GF2X_new "New<GF2X>"()
-    GF2X_c* GF2X_construct "Construct<GF2X>"(void *mem)
-    void GF2X_destruct "Destruct<GF2X>"(GF2X_c *mem)
-    void GF2X_delete "Delete<GF2X>"(GF2X_c *mem)
-    void GF2X_from_str "_from_str<GF2X>"(GF2X_c* dest, char* s)
-
-    void GF2X_add "add"( GF2X_c x, GF2X_c a, GF2X_c b)
-    void GF2X_sub "sub"( GF2X_c x, GF2X_c a, GF2X_c b)
-    void GF2X_mul "mul"( GF2X_c x, GF2X_c a, GF2X_c b)
-    void GF2X_negate "negate"(GF2X_c x, GF2X_c a)
-    void GF2X_power "power"(GF2X_c t, GF2X_c x, long e)
-
+    GF2X_c* GF2X_new "New<GF2X_c>"()
+    GF2X_c* GF2X_construct "Construct<GF2X_c>"(void *mem)
+    void GF2X_destruct "Destruct<GF2X_c>"(GF2X_c *mem)
+    void GF2X_delete "Delete<GF2X_c>"(GF2X_c *mem)
+    void GF2X_from_str "_from_str<GF2X_c>"(GF2X_c* dest, char* s)
+
+    GF2X_c* new_GF2X()
     GF2X_c* str_to_GF2X(char* s)
+    void del_GF2X(GF2X_c* n)
     char* GF2X_to_str(GF2X_c* x)
+    GF2X_c* GF2X_add(GF2X_c* x, GF2X_c* y)
+    GF2X_c* GF2X_sub(GF2X_c* x, GF2X_c* y)
+    GF2X_c* GF2X_mul(GF2X_c* x, GF2X_c* y)
+    GF2X_c* GF2X_pow(GF2X_c* x, long e)
     int GF2X_eq( GF2X_c* x,  GF2X_c* y)
     int GF2X_is_one(GF2X_c* x)
@@ -338,21 +288,19 @@
         pass
 
-    GF2E_c* GF2E_new "New<GF2E>"()
-    GF2E_c* GF2E_construct "Construct<GF2E>"(void *mem)
-    void GF2E_destruct "Destruct<GF2E>"(GF2E_c *mem)
-    void GF2E_delete "Delete<GF2E>"(GF2E_c *mem)
-    void GF2E_from_str "_from_str<GF2E>"(GF2E_c* dest, char* s)
-
-    void GF2E_add "add"( GF2E_c x, GF2E_c a, GF2E_c b)
-    void GF2E_sub "sub"( GF2E_c x, GF2E_c a, GF2E_c b)
-    void GF2E_mul "mul"( GF2E_c x, GF2E_c a, GF2E_c b)
-    void GF2E_negate "negate"(GF2E_c x, GF2E_c a)
-    void GF2E_power "power"(GF2E_c t, GF2E_c x, long e)
-    GF2E_c GF2E_random "random_GF2E"()
-    GF2X_c GF2E_rep "rep"(GF2E_c x)
+    GF2E_c* GF2E_new "New<GF2E_c>"()
+    GF2E_c* GF2E_construct "Construct<GF2E_c>"(void *mem)
+    void GF2E_destruct "Destruct<GF2E_c>"(GF2E_c *mem)
+    void GF2E_delete "Delete<GF2E_c>"(GF2E_c *mem)
+    void GF2E_from_str "_from_str<GF2E_c>"(GF2E_c* dest, char* s)
 
     void ntl_GF2E_set_modulus(GF2X_c *x)
+    GF2E_c* new_GF2E()
     GF2E_c* str_to_GF2E(char *s)
+    void del_GF2E(GF2E_c *n)
     char *GF2E_to_str(GF2E_c* x)
+    GF2E_c *GF2E_add(GF2E_c *x, GF2E_c *y)
+    GF2E_c *GF2E_sub(GF2E_c *x, GF2E_c *y)
+    GF2E_c *GF2E_mul(GF2E_c *x, GF2E_c *y)
+    GF2E_c *GF2E_pow(GF2E_c *x, long e)
     int GF2E_eq( GF2E_c* x,  GF2E_c* y)
     int GF2E_is_one(GF2E_c *x)
@@ -362,4 +310,5 @@
     long GF2E_degree()
     GF2X_c *GF2E_modulus()
+    GF2E_c *GF2E_random()
     long  GF2E_trace(GF2E_c *x)
     GF2X_c *GF2E_ntl_GF2X(GF2E_c *x)
@@ -369,15 +318,9 @@
         pass
 
-    GF2EX_c* GF2EX_new "New<GF2EX>"()
-    GF2EX_c* GF2EX_construct "Construct<GF2EX>"(void *mem)
-    void GF2EX_destruct "Destruct<GF2EX>"(GF2EX_c *mem)
-    void GF2EX_delete "Delete<GF2EX>"(GF2EX_c *mem)
-    void GF2EX_from_str "_from_str<GF2EX>"(GF2EX_c* dest, char* s)
-
-    void GF2EX_add "add"( GF2EX_c x, GF2EX_c a, GF2EX_c b)
-    void GF2EX_sub "sub"( GF2EX_c x, GF2EX_c a, GF2EX_c b)
-    void GF2EX_mul "mul"( GF2EX_c x, GF2EX_c a, GF2EX_c b)
-    void GF2EX_negate "negate"(GF2EX_c x, GF2EX_c a)
-    void GF2EX_power "power"(GF2EX_c t, GF2EX_c x, long e)
+    GF2EX_c* GF2EX_new "New<GF2EX_c>"()
+    GF2EX_c* GF2EX_construct "Construct<GF2EX_c>"(void *mem)
+    void GF2EX_destruct "Destruct<GF2EX_c>"(GF2EX_c *mem)
+    void GF2EX_delete "Delete<GF2EX_c>"(GF2EX_c *mem)
+    void GF2EX_from_str "_from_str<GF2EX_c>"(GF2EX_c* dest, char* s)
 
     GF2EX_c* new_GF2EX()
@@ -385,6 +328,11 @@
     void del_GF2EX(GF2EX_c* n)
     char* GF2EX_to_str(GF2EX_c* x)
+    GF2EX_c* GF2EX_add(GF2EX_c* x, GF2EX_c* y)
+    GF2EX_c* GF2EX_sub(GF2EX_c* x, GF2EX_c* y)
+    GF2EX_c* GF2EX_mul(GF2EX_c* x, GF2EX_c* y)
+    GF2EX_c* GF2EX_pow(GF2EX_c* x, long e)
     int GF2EX_is_one(GF2EX_c* x)
     int GF2EX_is_zero(GF2EX_c* x)
+    GF2EX_c* GF2EX_neg(GF2EX_c* x)
     GF2EX_c* GF2EX_copy(GF2EX_c* x)
 
@@ -394,29 +342,24 @@
         pass
 
-    mat_GF2E_c* mat_GF2E_new "New<mat_GF2E>"()
-    mat_GF2E_c* mat_GF2E_construct "Construct<mat_GF2E>"(void *mem)
-    void mat_GF2E_destruct "Destruct<mat_GF2E>"(mat_GF2E_c *mem)
-    void mat_GF2E_delete "Delete<mat_GF2E>"(mat_GF2E_c *mem)
-    void mat_GF2E_from_str "_from_str<mat_GF2E>"(mat_GF2E_c* dest, char* s)
-
-    void mat_GF2E_add "add"( mat_GF2E_c x, mat_GF2E_c a, mat_GF2E_c b)
-    void mat_GF2E_sub "sub"( mat_GF2E_c x, mat_GF2E_c a, mat_GF2E_c b)
-    void mat_GF2E_mul "mul"( mat_GF2E_c x, mat_GF2E_c a, mat_GF2E_c b)
-    void mat_GF2E_negate "negate"(mat_GF2E_c x, mat_GF2E_c a)
-    void mat_GF2E_power "power"(mat_GF2E_c t, mat_GF2E_c x, long e)
-    GF2E_c mat_GF2E_determinant "determinant"(mat_GF2E_c m)
-    void mat_GF2E_transpose "transpose"(mat_GF2E_c r, mat_GF2E_c m)
-
-    void mat_GF2E_SetDims(mat_GF2E_c* mGF2E, long nrows, long ncols)
+    mat_GF2E_c* mat_GF2E_new "New<mat_GF2E_c>"()
+    mat_GF2E_c* mat_GF2E_construct "Construct<mat_GF2E_c>"(void *mem)
+    void mat_GF2E_destruct "Destruct<mat_GF2E_c>"(mat_GF2E_c *mem)
+    void mat_GF2E_delete "Delete<mat_GF2E_c>"(mat_GF2E_c *mem)
+    void mat_GF2E_from_str "_from_str<mat_GF2E_c>"(mat_GF2E_c* dest, char* s)
+
+    mat_GF2E_c* new_mat_GF2E(long nrows, long ncols)
+    void del_mat_GF2E(mat_GF2E_c* n)
     char* mat_GF2E_to_str(mat_GF2E_c* x)
+    mat_GF2E_c* mat_GF2E_add(mat_GF2E_c* x, mat_GF2E_c* y)
+    mat_GF2E_c* mat_GF2E_sub(mat_GF2E_c* x, mat_GF2E_c* y)
+    mat_GF2E_c* mat_GF2E_mul(mat_GF2E_c* x, mat_GF2E_c* y)
+    mat_GF2E_c* mat_GF2E_pow(mat_GF2E_c* x, long e)
     long mat_GF2E_nrows(mat_GF2E_c* x)
     long mat_GF2E_ncols(mat_GF2E_c* x)
     void mat_GF2E_setitem(mat_GF2E_c* x, int i, int j, GF2E_c* z)
     GF2E_c* mat_GF2E_getitem(mat_GF2E_c* x, int i, int j)
+    GF2E_c* mat_GF2E_determinant(mat_GF2E_c* x)
     long mat_GF2E_gauss(mat_GF2E_c *x, long w)
     long mat_GF2E_is_zero(mat_GF2E_c *x)
-
-
-cdef extern from "ZZ_pylong.h":
-    object ZZ_get_pylong(ZZ_c z)
-    int ZZ_set_pylong(ZZ_c z, object ll)
+    mat_GF2E_c* mat_GF2E_transpose(mat_GF2E_c *x)
+ 
Index: sage/libs/ntl/init.pxi
===================================================================
--- sage/libs/ntl/init.pxi	(revision 0)
+++ sage/libs/ntl/init.pxi	(revision 0)
@@ -0,0 +1,8 @@
+cdef make_ZZ(ZZ* x):
+    cdef ntl_ZZ y
+    _sig_off
+    y = ntl_ZZ(_INIT)
+    #y.x = <ZZ*> x
+    y.set(<ZZ*> x)
+    return y
+
Index: sage/libs/ntl/ntl.pxd
===================================================================
--- sage/libs/ntl/ntl.pxd	(revision 6014)
+++ sage/libs/ntl/ntl.pxd	(revision 6014)
@@ -0,0 +1,55 @@
+# here's all the C/C++ definitions need to make NTL go from pyrex
+include "decl.pxi"
+
+cdef class ntl_ZZ:
+    cdef ZZ_c* x
+    cdef set(self, void *y)
+    cdef public int get_as_int(ntl_ZZ self)
+    cdef public void set_from_int(ntl_ZZ self, int value)
+
+cdef class ntl_ZZX:
+    cdef ZZX_c* x
+    cdef set(self, void *y)
+    cdef void setitem_from_int(ntl_ZZX self, long i, int value)
+    cdef int getitem_as_int(ntl_ZZX self, long i)
+
+cdef extern from "ntl_wrap.h":
+    cdef int ZZ_p_to_int(ZZ_p_c* x)
+    cdef ZZ_p_c* int_to_ZZ_p(int value)
+    cdef void ZZ_p_set_from_int(ZZ_p_c* x, int value)
+
+cdef class ntl_ZZ_p:
+    cdef ZZ_p_c* x
+    cdef set(self, void *y)
+    cdef public int get_as_int(ntl_ZZ_p self)
+    cdef public void set_from_int(ntl_ZZ_p self, int value)
+
+cdef extern from "ntl_wrap.h":
+    cdef void ZZ_pX_setitem_from_int(ZZ_pX_c* x, long i, int value)
+    cdef int ZZ_pX_getitem_as_int(ZZ_pX_c* x, long i)
+    
+cdef class ntl_ZZ_pX:
+    cdef ZZ_pX_c* x
+    cdef set(self, void *y)
+    cdef void setitem_from_int(ntl_ZZ_pX self, long i, int value)
+    cdef int getitem_as_int(ntl_ZZ_pX self, long i)
+
+cdef class ntl_mat_ZZ:
+    cdef mat_ZZ_c* x
+    cdef long __nrows, __ncols
+
+cdef class ntl_GF2X:
+    cdef GF2X_c* gf2x_x
+    cdef set(self,void *y)
+
+cdef class ntl_GF2E(ntl_GF2X):
+    cdef GF2E_c* gf2e_x
+    cdef set(self,void *y)
+
+cdef class ntl_mat_GF2E:
+    cdef mat_GF2E_c* x
+    cdef long __nrows, __ncols
+
+cdef class ntl_GF2EX:
+    cdef GF2EX_c* x
+    cdef set(self,void *y)
Index: sage/libs/ntl/ntl.pxi
===================================================================
--- sage/libs/ntl/ntl.pxi	(revision 6014)
+++ sage/libs/ntl/ntl.pxi	(revision 6014)
@@ -0,0 +1,5 @@
+cdef extern object (make_GF2E(GF2E_c (*)))
+cdef extern object (make_GF2EX(GF2EX_c (*)))
+cdef extern object (make_GF2X(GF2X_c (*)))
+cdef extern object (make_ZZ(ZZ_c (*)))
+cdef extern object (make_ZZ_p(ZZ_p_c (*)))
Index: sage/libs/ntl/ntl.pyx
===================================================================
--- sage/libs/ntl/ntl.pyx	(revision 6019)
+++ sage/libs/ntl/ntl.pyx	(revision 6019)
@@ -0,0 +1,3379 @@
+"""
+NTL wrapper
+
+AUTHORS:
+   - William Stein
+   - Martin Albrecht <malb@informatik.uni-bremen.de>
+   - David Harvey (2007-02): speed up getting data in/out of NTL
+   - Joel B. Mohler:  fast conversions to and from sage Integer type
+"""
+
+#*****************************************************************************
+#       Copyright (C) 2005 William Stein <wstein@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/
+#*****************************************************************************
+
+include "../../ext/interrupt.pxi"
+include "../../ext/stdsage.pxi"
+include 'misc.pxi'
+include 'decl.pxi'
+
+from sage.rings.integer import Integer
+from sage.rings.integer_ring import IntegerRing
+from sage.rings.integer cimport Integer
+from sage.rings.integer_ring cimport IntegerRing_class
+
+ZZ_sage = IntegerRing()
+
+
+##############################################################################
+# ZZ: Arbitrary precision integers
+##############################################################################
+
+cdef class ntl_ZZ:
+    r"""
+    The \class{ZZ} class is used to represent signed, arbitrary length integers.
+
+    Routines are provided for all of the basic arithmetic operations, as
+    well as for some more advanced operations such as primality testing.
+    Space is automatically managed by the constructors and destructors.
+
+    This module also provides routines for generating small primes, and
+    fast routines for performing modular arithmetic on single-precision
+    numbers.
+    """
+    # See ntl.pxd for definition of data members
+
+    def __dealloc__(self):
+        del_ZZ(self.x)
+
+    def __repr__(self):
+        _sig_on
+        return string(ZZ_to_str(self.x))
+
+    def __reduce__(self):
+        raise NotImplementedError
+
+    def __mul__(ntl_ZZ self, other):
+        cdef ntl_ZZ y
+        if not isinstance(other, ntl_ZZ):
+            other = ntl_ZZ(other)
+        y = other
+        _sig_on
+        return make_ZZ(ZZ_mul(self.x, y.x))
+            
+    def __sub__(ntl_ZZ self, other):
+        cdef ntl_ZZ y
+        if not isinstance(other, ntl_ZZ):
+            other = ntl_ZZ(other)
+        y = other
+        _sig_on
+        return make_ZZ(ZZ_sub(self.x, y.x))
+
+    def __add__(ntl_ZZ self, other):
+        cdef ntl_ZZ y
+        if not isinstance(other, ntl_ZZ):
+            other = ntl_ZZ(other)
+        y = other
+        _sig_on
+        return make_ZZ(ZZ_add(self.x, y.x))
+            
+    def __neg__(ntl_ZZ self):
+        _sig_on
+        return make_ZZ(ZZ_neg(self.x))
+
+    def __pow__(ntl_ZZ self, long e, ignored):
+        _sig_on
+        return make_ZZ(ZZ_pow(self.x, e))
+    
+    cdef set(self, void *y):  # only used internally for initialization; assumes self.x not set yet!
+        self.x = <ZZ_c*> y
+
+    cdef int get_as_int(ntl_ZZ self):
+        r"""
+        Returns value as C int.
+        Return value is only valid if the result fits into an int.
+        
+        AUTHOR: David Harvey (2006-08-05)
+        """
+        return ZZ_to_int(self.x)
+
+    def get_as_int_doctest(self):
+        r"""
+        This method exists solely for automated testing of get_as_int().
+
+        sage: x = ntl.ZZ(42)
+        sage: i = x.get_as_int_doctest()
+        sage: print i
+         42
+        sage: print type(i)
+         <type 'int'>
+        """
+        return self.get_as_int()
+
+    def get_as_sage_int(self):
+        r"""
+        Gets the value as a sage int.
+
+        sage: n=ntl.ZZ(2983)
+        sage: type(n.get_as_sage_int())
+        <type 'sage.rings.integer.Integer'>
+
+        AUTHOR: Joel B. Mohler
+        """
+        return (<IntegerRing_class>ZZ_sage)._coerce_ZZ(self.x)
+
+    cdef void set_from_int(ntl_ZZ self, int value):
+        r"""
+        Sets the value from a C int.
+
+        AUTHOR: David Harvey (2006-08-05)
+        """
+        ZZ_set_from_int(self.x, value)
+
+    def set_from_sage_int(self, Integer value):
+        r"""
+        Sets the value from a sage int.
+
+        sage: n=ntl.ZZ(2983)
+        sage: n
+        2983
+        sage: n.set_from_sage_int(1234)
+        sage: n
+        1234
+
+        AUTHOR: Joel B. Mohler
+        """
+        value._to_ZZ(self.x)
+
+    def set_from_int_doctest(self, value):
+        r"""
+        This method exists solely for automated testing of set_from_int().
+
+        sage: x = ntl.ZZ()
+        sage: x.set_from_int_doctest(42)
+        sage: x
+         42
+        """
+        self.set_from_int(int(value))
+
+    # todo: add wrapper for int_to_ZZ in wrap.cc?
+                                            
+        
+cdef public make_ZZ(ZZ_c* x):
+    cdef ntl_ZZ y
+    _sig_off
+    y = ntl_ZZ()
+    y.x = x
+    return y
+
+def make_new_ZZ(x='0'):
+    s = str(x)
+    cdef ntl_ZZ n
+    n = ntl_ZZ()
+    _sig_on
+    n.x = str_to_ZZ(s)
+    _sig_off
+    return n
+
+# Random-number generation 
+def ntl_setSeed(x=None):
+    """
+    Seed the NTL random number generator.
+
+    EXAMPLE:
+        sage: ntl.ntl_setSeed(10)
+        sage: ntl.ZZ_random(1000)
+        776
+    """
+    cdef ntl_ZZ seed
+    if x is None:
+        from random import randint
+        seed = make_new_ZZ(str(randint(0,int(2)**64)))
+    else:
+        seed = make_new_ZZ(str(x))
+    _sig_on
+    setSeed(seed.x)
+    _sig_off
+
+ntl_setSeed()
+
+def randomBnd(q):
+    r""" 
+    Returns cryptographically-secure random number in the range [0,n)
+    
+    EXAMPLES:
+        sage: [ntl.ZZ_random(99999) for i in range(5)]
+        [53357, 19674, 69528, 87029, 28752]
+        
+    AUTHOR: 
+        -- Didier Deshommes <dfdeshom@gmail.com>
+    """
+    cdef ntl_ZZ w
+    
+    if not isinstance(q, ntl_ZZ):
+        q = make_new_ZZ(str(q))
+    w = q
+    _sig_on
+    return  make_ZZ(ZZ_randomBnd(w.x))
+        
+def randomBits(long n):
+    r"""
+    Return a pseudo-random number between 0 and $2^n-1$
+
+    EXAMPLES:
+        sage: [ntl.ZZ_random_bits(20) for i in range(3)]
+        [1025619, 177635, 766262]
+        
+    AUTHOR:
+        -- Didier Deshommes <dfdeshom@gmail.com>
+    """
+    _sig_on 
+    return make_ZZ(ZZ_randomBits(n))
+
+
+##############################################################################
+#
+# ZZX: polynomials over the integers
+#
+##############################################################################
+
+
+cdef class ntl_ZZX:
+    r"""
+    The class \class{ZZX} implements polynomials in $\Z[X]$, i.e.,
+    univariate polynomials with integer coefficients.
+    
+    Polynomial multiplication is very fast, and is implemented using
+    one of 4 different algorithms:
+    \begin{enumerate}
+    \item\hspace{1em} Classical
+    \item\hspace{1em} Karatsuba
+    \item\hspace{1em} Schoenhage and Strassen --- performs an FFT by working
+          modulo a "Fermat number" of appropriate size...
+          good for polynomials with huge coefficients
+          and moderate degree
+    \item\hspace{1em} CRT/FFT --- performs an FFT by working modulo several
+         small primes.  This is good for polynomials with moderate
+         coefficients and huge degree.
+    \end{enumerate}
+    
+    The choice of algorithm is somewhat heuristic, and may not always be
+    perfect.
+      
+    Many thanks to Juergen Gerhard {\tt
+    <jngerhar@plato.uni-paderborn.de>} for pointing out the deficiency
+    in the NTL-1.0 ZZX arithmetic, and for contributing the
+    Schoenhage/Strassen code.
+    
+    Extensive use is made of modular algorithms to enhance performance
+    (e.g., the GCD algorithm and many others).
+    """
+
+    # See ntl_ZZX.pxd for definition of data members
+    def __init__(self):
+        """
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,5,-9])
+            sage: f
+            [1 2 5 -9]
+            sage: g = ntl.ZZX([0,0,0]); g
+            []
+            sage: g[10]=5
+            sage: g
+            [0 0 0 0 0 0 0 0 0 0 5]
+            sage: g[10]
+            5
+        """
+        return
+
+    def __reduce__(self):
+        raise NotImplementedError
+
+    def __dealloc__(self):
+        if self.x:
+            ZZX_dealloc(self.x)
+                
+    def __repr__(self):
+        _sig_on
+        return string_delete(ZZX_repr(self.x))
+
+    def copy(self):
+        return make_ZZX(ZZX_copy(self.x))
+
+    def __copy__(self):
+        return make_ZZX(ZZX_copy(self.x))
+
+    def __setitem__(self, long i, a):
+        if i < 0:
+            raise IndexError, "index (i=%s) must be >= 0"%i
+        a = str(int(a))
+        ZZX_setitem(self.x, i, a)
+
+    cdef void setitem_from_int(ntl_ZZX self, long i, int value):
+        r"""
+        Sets ith coefficient to value.
+
+        AUTHOR: David Harvey (2006-08-05)
+        """        
+        ZZX_setitem_from_int(self.x, i, value)
+
+    def setitem_from_int_doctest(self, i, value):
+        r"""
+        This method exists solely for automated testing of setitem_from_int().
+
+        sage: x = ntl.ZZX([2, 3, 4])
+        sage: x.setitem_from_int_doctest(5, 42)
+        sage: x
+         [2 3 4 0 0 42]
+        """
+        self.setitem_from_int(int(i), int(value))
+
+    def __getitem__(self, unsigned int i):
+        r"""
+        Retrieves coefficient number i as a SAGE Integer.
+        
+        sage: x = ntl.ZZX([129381729371289371237128318293718237, 2, -3, 0, 4])
+        sage: x[0]
+         129381729371289371237128318293718237
+        sage: type(x[0])
+         <type 'sage.rings.integer.Integer'>
+        sage: x[1]
+         2
+        sage: x[2]
+         -3
+        sage: x[3]
+         0
+        sage: x[4]
+         4
+        sage: x[5]
+         0
+        """
+        cdef Integer output
+        output = PY_NEW(Integer)
+        ZZX_getitem_as_mpz(&output.value, self.x, i)
+        return output
+
+    cdef int getitem_as_int(ntl_ZZX self, long i):
+        r"""
+        Returns ith coefficient as C int.
+        Return value is only valid if the result fits into an int.
+
+        AUTHOR: David Harvey (2006-08-05)
+        """        
+        return ZZX_getitem_as_int(self.x, i)
+
+    def getitem_as_int_doctest(self, i):
+        r"""
+        This method exists solely for automated testing of getitem_as_int().
+
+        sage: x = ntl.ZZX([2, 3, 5, -7, 11])
+        sage: i = x.getitem_as_int_doctest(3)
+        sage: print i
+         -7
+        sage: print type(i)
+         <type 'int'>
+        sage: print x.getitem_as_int_doctest(15)
+         0
+        """
+        return self.getitem_as_int(i)
+
+    def list(self):
+        r"""
+        Retrieves coefficients as a list of SAGE Integers.
+        
+        EXAMPLES:
+            sage: x = ntl.ZZX([129381729371289371237128318293718237, 2, -3, 0, 4])
+            sage: L = x.list(); L
+            [129381729371289371237128318293718237, 2, -3, 0, 4]
+            sage: type(L[0])
+            <type 'sage.rings.integer.Integer'>
+            sage: x = ntl.ZZX()
+            sage: L = x.list(); L
+            []
+        """
+        cdef int i
+        return [self[i] for i from 0 <= i <= ZZX_degree(self.x)]
+    
+
+    def __add__(ntl_ZZX self, ntl_ZZX other):
+        """
+        EXAMPLES:
+            sage: ntl.ZZX(range(5)) + ntl.ZZX(range(6))
+            [0 2 4 6 8 5]
+        """
+        return make_ZZX(ZZX_add(self.x, other.x))
+
+    def __sub__(ntl_ZZX self, ntl_ZZX other):
+        """
+        EXAMPLES:
+            sage: ntl.ZZX(range(5)) - ntl.ZZX(range(6))
+            [0 0 0 0 0 -5]
+        """
+        return make_ZZX(ZZX_sub(self.x, other.x))
+
+    def __mul__(ntl_ZZX self, ntl_ZZX other):
+        """
+        EXAMPLES:
+            sage: ntl.ZZX(range(5)) * ntl.ZZX(range(6))
+            [0 0 1 4 10 20 30 34 31 20]
+        """
+        _sig_on
+        return make_ZZX(ZZX_mul(self.x, other.x))
+
+    def __div__(ntl_ZZX self, ntl_ZZX other):
+        """
+        Compute quotient self / other, if the quotient is a polynomial.
+        Otherwise an Exception is raised.
+        
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])**2
+            sage: g = ntl.ZZX([4,5])
+            sage: f/g
+            [4 13 22 15]
+            sage: ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])
+            [4 13 22 15]
+
+            sage: f = ntl.ZZX(range(10)); g = ntl.ZZX([-1,0,1])
+            sage: f/g
+            Traceback (most recent call last):
+            ...
+            ArithmeticError: self (=[0 1 2 3 4 5 6 7 8 9]) is not divisible by other (=[-1 0 1])
+        """
+        _sig_on
+        cdef int divisible
+        cdef ZZX_c* q
+        q = ZZX_div(self.x, other.x, &divisible)
+        if not divisible:
+            raise ArithmeticError, "self (=%s) is not divisible by other (=%s)"%(self, other)
+        return make_ZZX(q)
+
+    def __mod__(ntl_ZZX self, ntl_ZZX other):
+        """
+        Given polynomials a, b in ZZ[X], there exist polynomials q, r
+        in QQ[X] such that a = b*q + r, deg(r) < deg(b).  This
+        function returns q if q lies in ZZ[X], and otherwise raises an
+        Exception.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([2,4,6]); g = ntl.ZZX([2])
+            sage: f % g   # 0
+            []
+
+            sage: f = ntl.ZZX(range(10)); g = ntl.ZZX([-1,0,1])
+            sage: f % g
+            [20 25]
+        """
+        _sig_on
+        return make_ZZX(ZZX_mod(self.x, other.x))
+
+    def quo_rem(self, ntl_ZZX other):
+        """
+        Returns the unique integral q and r such that self = q*other +
+        r, if they exist.  Otherwise raises an Exception.
+
+        EXAMPLES:
+           sage: f = ntl.ZZX(range(10)); g = ntl.ZZX([-1,0,1])
+           sage: q, r = f.quo_rem(g)
+           sage: q, r
+           ([20 24 18 21 14 16 8 9], [20 25])
+           sage: q*g + r == f
+           True
+        """
+        cdef ZZX_c *r, *q
+        _sig_on
+        ZZX_quo_rem(self.x, other.x, &r, &q)
+        return (make_ZZX(q), make_ZZX(r))
+
+    def square(self):
+        """
+        Return f*f.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([-1,0,1])
+            sage: f*f
+            [1 0 -2 0 1]
+        """
+        _sig_on
+        return make_ZZX(ZZX_square(self.x))
+
+    def __pow__(ntl_ZZX self, long n, ignored):
+        """
+        Return the n-th nonnegative power of self.
+
+        EXAMPLES:
+            sage: g = ntl.ZZX([-1,0,1])
+            sage: g**10
+            [1 0 -10 0 45 0 -120 0 210 0 -252 0 210 0 -120 0 45 0 -10 0 1]
+        """
+        if n < 0:
+            raise NotImplementedError
+        import sage.rings.arith
+        return sage.rings.arith.generic_power(self, n, one_ZZX.copy())
+
+    def __cmp__(ntl_ZZX self, ntl_ZZX other):
+        """
+        Decide whether or not self and other are equal.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,3])
+            sage: g = ntl.ZZX([1,2,3,0])
+            sage: f == g
+            True
+            sage: g = ntl.ZZX([0,1,2,3])
+            sage: f == g
+            False
+        """
+        if ZZX_equal(self.x, other.x):
+            return 0
+        return -1
+
+    def is_zero(self):
+        """
+        Return True exactly if this polynomial is 0.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([0,0,0,0])
+            sage: f.is_zero()
+            True
+            sage: f = ntl.ZZX([0,0,1])
+            sage: f
+            [0 0 1]
+            sage: f.is_zero()
+            False
+        """
+        return bool(ZZX_is_zero(self.x))
+
+    def is_one(self):
+        """
+        Return True exactly if this polynomial is 1.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,1])
+            sage: f.is_one()
+            False
+            sage: f = ntl.ZZX([1])
+            sage: f.is_one()
+            True
+        """
+        return bool(ZZX_is_one(self.x))
+
+    def is_monic(self):
+        """
+        Return True exactly if this polynomial is monic.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([2,0,0,1])
+            sage: f.is_monic()
+            True
+            sage: g = f.reverse()
+            sage: g.is_monic()
+            False
+            sage: g
+            [1 0 0 2]
+        """
+        if ZZX_is_zero(self.x):
+             return False
+        return bool(ZZ_is_one(ZZX_leading_coefficient(self.x)))
+
+        # return bool(ZZX_is_monic(self.x))
+
+    def __neg__(self):
+        """
+        Return the negative of self.
+        EXAMPLES:
+            sage: f = ntl.ZZX([2,0,0,1])
+            sage: -f
+            [-2 0 0 -1]
+        """
+        return make_ZZX(ZZX_neg(self.x))
+
+    def left_shift(self, long n):
+        """
+        Return the polynomial obtained by shifting all coefficients of
+        this polynomial to the left n positions.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([2,0,0,1])
+            sage: f
+            [2 0 0 1]
+            sage: f.left_shift(2)
+            [0 0 2 0 0 1]
+            sage: f.left_shift(5)
+            [0 0 0 0 0 2 0 0 1]
+
+        A negative left shift is a right shift.
+            sage: f.left_shift(-2)
+            [0 1]
+        """
+        return make_ZZX(ZZX_left_shift(self.x, n))
+        
+    def right_shift(self, long n):
+        """
+        Return the polynomial obtained by shifting all coefficients of
+        this polynomial to the right n positions.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([2,0,0,1])
+            sage: f
+            [2 0 0 1]
+            sage: f.right_shift(2)
+            [0 1]
+            sage: f.right_shift(5)
+            []
+            sage: f.right_shift(-2)
+            [0 0 2 0 0 1]
+        """
+        return make_ZZX(ZZX_right_shift(self.x, n))
+
+    def content(self):
+        """
+        Return the content of f, which has sign the same as the
+        leading coefficient of f.  Also, our convention is that the
+        content of 0 is 0.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([2,0,0,2])
+            sage: f.content()
+            2
+            sage: f = ntl.ZZX([2,0,0,-2])
+            sage: f.content()
+            -2
+            sage: f = ntl.ZZX([6,12,3,9])
+            sage: f.content()
+            3
+            sage: f = ntl.ZZX([])
+            sage: f.content()
+            0
+        """
+        cdef char* t
+        t = ZZX_content(self.x)
+        return int(string(t))
+
+    def primitive_part(self):
+        """
+        Return the primitive part of f.  Our convention is that the leading
+        coefficient of the primitive part is nonnegegative, and the primitive
+        part of 0 is 0.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([6,12,3,9])
+            sage: f.primitive_part()
+            [2 4 1 3]
+            sage: f
+            [6 12 3 9]
+            sage: f = ntl.ZZX([6,12,3,-9])
+            sage: f
+            [6 12 3 -9]
+            sage: f.primitive_part()
+            [-2 -4 -1 3]
+            sage: f = ntl.ZZX()
+            sage: f.primitive_part()
+            []
+        """
+        return make_ZZX(ZZX_primitive_part(self.x))
+
+    def pseudo_quo_rem(self, ntl_ZZX other):
+        r"""
+        Performs pseudo-division: computes q and r with deg(r) <
+        deg(b), and \code{LeadCoeff(b)\^(deg(a)-deg(b)+1) a = b q + r}.
+        Only the classical algorithm is used.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([0,1])
+            sage: g = ntl.ZZX([1,2,3])
+            sage: g.pseudo_quo_rem(f)
+            ([2 3], [1])
+            sage: f = ntl.ZZX([1,1])
+            sage: g.pseudo_quo_rem(f)
+            ([-1 3], [2])
+        """
+        cdef ZZX_c *r, *q
+        _sig_on
+        ZZX_pseudo_quo_rem(self.x, other.x, &r, &q)
+        return (make_ZZX(q), make_ZZX(r))
+
+    def gcd(self, ntl_ZZX other):
+        """
+        Return the gcd d = gcd(a, b), where by convention the leading coefficient
+        of d is >= 0.  We use a multi-modular algorithm.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])**2
+            sage: g = ntl.ZZX([1,1,1])**3 * ntl.ZZX([1,2,3])
+            sage: f.gcd(g)
+            [1 2 3]
+            sage: g.gcd(f)
+            [1 2 3]
+        """
+        _sig_on
+        return make_ZZX(ZZX_gcd(self.x, other.x))
+
+    def lcm(self, ntl_ZZX other):
+        """
+        Return the least common multiple of self and other.
+        """
+        g = self.gcd(other)
+        return (self*other).quo_rem(g)[0]
+
+    def xgcd(self, ntl_ZZX other, proof=True):
+        """
+        If self and other are coprime over the rationals, return r, s,
+        t such that r = s*self + t*other.  Otherwise return 0.  This
+        is \emph{not} the same as the \sage function on polynomials
+        over the integers, since here the return value r is always an
+        integer.
+            
+        Here r is the resultant of a and b; if r != 0, then this
+        function computes s and t such that: a*s + b*t = r; otherwise
+        s and t are both 0.  If proof = False (*not* the default),
+        then resultant computation may use a randomized strategy that
+        errs with probability no more than $2^{-80}$.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])**2
+            sage: g = ntl.ZZX([1,1,1])**3 * ntl.ZZX([1,2,3])
+            sage: f.xgcd(g)   # nothing since they are not coprime
+            (0, [], [])
+    
+        In this example the input quadratic polynomials have a common root modulo 13.
+            sage: f = ntl.ZZX([5,0,1])
+            sage: g = ntl.ZZX([18,0,1])
+            sage: f.xgcd(g)
+            (169, [-13], [13])
+        """
+        cdef ZZX_c *s, *t
+        cdef ZZ_c *r 
+        _sig_on
+        ZZX_xgcd(self.x, other.x, &r, &s, &t, proof)
+        return (make_ZZ(r), make_ZZX(s), make_ZZX(t))
+
+    def degree(self):
+        """
+        Return the degree of this polynomial.  The degree of the 0
+        polynomial is -1.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([5,0,1])
+            sage: f.degree()
+            2
+            sage: f = ntl.ZZX(range(100))
+            sage: f.degree()
+            99
+            sage: f = ntl.ZZX()
+            sage: f.degree()
+            -1
+            sage: f = ntl.ZZX([1])
+            sage: f.degree()
+            0
+        """
+        return ZZX_degree(self.x)
+
+    def leading_coefficient(self):
+        """
+        Return the leading coefficient of this polynomial.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([3,6,9])
+            sage: f.leading_coefficient()
+            9
+            sage: f = ntl.ZZX()
+            sage: f.leading_coefficient()
+            0
+        """
+        return make_ZZ(ZZX_leading_coefficient(self.x))
+
+    def constant_term(self):
+        """
+        Return the constant coefficient of this polynomial.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([3,6,9])
+            sage: f.constant_term()
+            3
+            sage: f = ntl.ZZX()
+            sage: f.constant_term()
+            0
+        """
+        cdef char* t
+        t = ZZX_constant_term(self.x)
+        return int(string(t))
+
+    def set_x(self):
+        """
+        Set this polynomial to the monomial "x".
+
+        EXAMPLES:
+            sage: f = ntl.ZZX()
+            sage: f.set_x()
+            sage: f
+            [0 1]
+            sage: g = ntl.ZZX([0,1])
+            sage: f == g
+            True
+
+        Though f and g are equal, they are not the same objects in memory:
+            sage: f is g
+            False
+            
+        """
+        ZZX_set_x(self.x)
+
+    def is_x(self):
+        """
+        True if this is the polynomial "x".
+
+        EXAMPLES:
+            sage: f = ntl.ZZX()
+            sage: f.set_x()
+            sage: f.is_x()
+            True
+            sage: f = ntl.ZZX([0,1])
+            sage: f.is_x()
+            True
+            sage: f = ntl.ZZX([1])
+            sage: f.is_x()
+            False
+        """
+        return bool(ZZX_is_x(self.x))
+
+    def derivative(self):
+        """
+        Return the derivative of this polynomial.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,7,0,13])
+            sage: f.derivative()
+            [7 0 39]
+        """
+        return make_ZZX(ZZX_derivative(self.x))
+
+    def reverse(self, hi=None):
+        """
+        Return the polynomial obtained by reversing the coefficients
+        of this polynomial.  If hi is set then this function behaves
+        as if this polynomial has degree hi.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,3,4,5])
+            sage: f.reverse()
+            [5 4 3 2 1]
+            sage: f.reverse(hi=10)
+            [0 0 0 0 0 0 5 4 3 2 1]
+            sage: f.reverse(hi=2)
+            [3 2 1]
+            sage: f.reverse(hi=-2)
+            []
+        """
+        if not (hi is None):
+            return make_ZZX(ZZX_reverse_hi(self.x, int(hi)))
+        else:
+            return make_ZZX(ZZX_reverse(self.x))
+
+    def truncate(self, long m):
+        """
+        Return the truncation of this polynomial obtained by
+        removing all terms of degree >= m.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,3,4,5])
+            sage: f.truncate(3)
+            [1 2 3]
+            sage: f.truncate(8)
+            [1 2 3 4 5]
+            sage: f.truncate(1)
+            [1]
+            sage: f.truncate(0)
+            []
+            sage: f.truncate(-1)
+            []
+            sage: f.truncate(-5)
+            []
+        """
+        if m <= 0:
+            return zero_ZZX.copy()
+        return make_ZZX(ZZX_truncate(self.x, m))
+
+    def multiply_and_truncate(self, ntl_ZZX other, long m):
+        """
+        Return self*other but with terms of degree >= m removed.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,3,4,5])
+            sage: g = ntl.ZZX([10])
+            sage: f.multiply_and_truncate(g, 2)
+            [10 20]
+            sage: g.multiply_and_truncate(f, 2)
+            [10 20]
+        """
+        if m <= 0:
+            return zero_ZZX.copy()
+        return make_ZZX(ZZX_multiply_and_truncate(self.x, other.x, m))
+
+    def square_and_truncate(self, long m):
+        """
+        Return self*self but with terms of degree >= m removed.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,3,4,5])
+            sage: f.square_and_truncate(4)
+            [1 4 10 20]
+            sage: (f*f).truncate(4)
+            [1 4 10 20]
+        """
+        if m < 0:
+            return zero_ZZX.copy()
+        return make_ZZX(ZZX_square_and_truncate(self.x, m))
+
+    def invert_and_truncate(self, long m):
+        """
+        Compute and return the inverse of self modulo $x^m$.
+        The constant term of self must be 1 or -1.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,3,4,5,6,7])
+            sage: f.invert_and_truncate(20)
+            [1 -2 1 0 0 0 0 8 -23 22 -7 0 0 0 64 -240 337 -210 49]
+            sage: g = f.invert_and_truncate(20)
+            sage: g * f
+            [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -512 1344 -1176 343]
+        """
+        if m < 0:
+            raise ArithmeticError, "m (=%s) must be positive"%m
+        n = self.constant_term()
+        if n != 1 and n != -1:
+            raise ArithmeticError, \
+                  "The constant term of self must be 1 or -1."
+        _sig_on        
+        return make_ZZX(ZZX_invert_and_truncate(self.x, m))
+        
+    def multiply_mod(self, ntl_ZZX other, ntl_ZZX modulus):
+        """
+        Return self*other % modulus.  The modulus must be monic with
+        deg(modulus) > 0, and self and other must have smaller degree.
+        
+        EXAMPLES:
+            sage: modulus = ntl.ZZX([1,2,0,1])    # must be monic
+            sage: g = ntl.ZZX([-1,0,1])
+            sage: h = ntl.ZZX([3,7,13])
+            sage: h.multiply_mod(g, modulus)
+            [-10 -34 -36]
+        """
+        _sig_on
+        return make_ZZX(ZZX_multiply_mod(self.x, other.x, modulus.x))
+
+    def trace_mod(self, ntl_ZZX modulus):
+        """
+        Return the trace of this polynomial modulus the modulus.
+        The modulus must be monic, and of positive degree degree bigger
+        than the the degree of self.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,0,3])
+            sage: mod = ntl.ZZX([5,3,-1,1,1])
+            sage: f.trace_mod(mod)
+            -37
+        """
+        _sig_on
+        return make_ZZ(ZZX_trace_mod(self.x, modulus.x))
+
+    def trace_list(self):
+        """
+        Return the list of traces of the powers $x^i$ of the
+        monomial x modulo this polynomial for i = 0, ..., deg(f)-1.
+        This polynomial must be monic.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,0,3,0,1])
+            sage: f.trace_list()
+            [5, 0, -6, 0, 10]
+
+        The input polynomial must be monic or a ValueError is raised:
+            sage: f = ntl.ZZX([1,2,0,3,0,2])
+            sage: f.trace_list()
+            Traceback (most recent call last):
+            ...
+            ValueError: polynomial must be monic.
+        """
+        if not self.is_monic():
+            raise ValueError, "polynomial must be monic."
+        _sig_on
+        cdef char* t
+        t = ZZX_trace_list(self.x)
+        return eval(string(t).replace(' ', ','))
+
+    def resultant(self, ntl_ZZX other, proof=True):
+        """
+        Return the resultant of self and other.  If proof = False (the
+        default is proof=True), then this function may use a
+        randomized strategy that errors with probability no more than
+        $2^{-80}$.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([17,0,1,1])
+            sage: g = ntl.ZZX([34,-17,18,2])
+            sage: f.resultant(g)
+            1345873
+            sage: f.resultant(g, proof=False)
+            1345873
+        """
+        # NOTES: Within a factor of 2 in speed compared to MAGMA.
+        _sig_on
+        return make_ZZ(ZZX_resultant(self.x, other.x, proof))
+
+    def norm_mod(self, ntl_ZZX modulus, proof=True):
+        """
+        Return the norm of this polynomial modulo the modulus.  The
+        modulus must be monic, and of positive degree strictly greater
+        than the degree of self.  If proof=False (the default is
+        proof=True) then it may use a randomized strategy that errors
+        with probability no more than $2^{-80}$.
+
+
+        EXAMPLE:
+            sage: f = ntl.ZZX([1,2,0,3])
+            sage: mod = ntl.ZZX([-5,2,0,0,1])
+            sage: f.norm_mod(mod)
+            -8846
+
+        The norm is the constant term of the characteristic polynomial.
+            sage: f.charpoly_mod(mod)
+            [-8846 -594 -60 14 1]
+        """
+        _sig_on
+        return make_ZZ(ZZX_norm_mod(self.x, modulus.x, proof))
+
+    def discriminant(self, proof=True):
+        r"""
+        Return the discriminant of self, which is by definition
+        $$
+                (-1)^{m(m-1)/2} {\mbox{\tt resultant}}(a, a')/lc(a),
+        $$      
+        where m = deg(a), and lc(a) is the leading coefficient of a.
+        If proof is False (the default is True), then this function
+        may use a randomized strategy that errors with probability no
+        more than $2^{-80}$.
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,0,3])
+            sage: f.discriminant()
+            -339
+            sage: f.discriminant(proof=False)
+            -339
+        """
+        _sig_on
+        return make_ZZ(ZZX_discriminant(self.x, proof))
+
+    #def __call__(self, ntl_ZZ a):
+    #    _sig_on
+    #    return make_ZZ(ZZX_polyeval(self.x, a.x))
+
+    def charpoly_mod(self, ntl_ZZX modulus, proof=True):
+        """
+        Return the characteristic polynomial of this polynomial modulo
+        the modulus.  The modulus must be monic of degree bigger than
+        self. If proof=False (the default is True), then this function
+        may use a randomized strategy that errors with probability no
+        more than $2^{-80}$.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,0,3])
+            sage: mod = ntl.ZZX([-5,2,0,0,1])
+            sage: f.charpoly_mod(mod)
+            [-8846 -594 -60 14 1]
+
+        """
+        _sig_on
+        return make_ZZX(ZZX_charpoly_mod(self.x, modulus.x, proof))
+
+    def minpoly_mod_noproof(self, ntl_ZZX modulus):
+        """
+        Return the minimal polynomial of this polynomial modulo the
+        modulus.  The modulus must be monic of degree bigger than
+        self.  In all cases, this function may use a randomized
+        strategy that errors with probability no more than $2^{-80}$.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([0,0,1])
+            sage: g = f*f
+            sage: f.charpoly_mod(g)
+            [0 0 0 0 1]
+
+        However, since $f^2 = 0$ moduluo $g$, its minimal polynomial
+        is of degree $2$.
+            sage: f.minpoly_mod_noproof(g)
+            [0 0 1]
+        """
+        _sig_on
+        return make_ZZX(ZZX_minpoly_mod(self.x, modulus.x))
+
+    def clear(self):
+        """
+        Reset this polynomial to 0.  Changes this polynomial in place.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,3])
+            sage: f
+            [1 2 3]
+            sage: f.clear()
+            sage: f
+            []
+        """
+        ZZX_clear(self.x)
+
+    def preallocate_space(self, long n):
+        """
+        Pre-allocate spaces for n coefficients.  The polynomial that f
+        represents is unchanged.  This is useful if you know you'll be
+        setting coefficients up to n, so memory isn't re-allocated as
+        the polynomial grows.  (You might save a millisecond with this
+        function.)
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([1,2,3])
+            sage: f.preallocate_space(20)
+            sage: f
+            [1 2 3]
+            sage: f[10]=5  # no new memory is allocated
+            sage: f
+            [1 2 3 0 0 0 0 0 0 0 5]
+        """
+        _sig_on
+        ZZX_preallocate_space(self.x, n)
+        _sig_off
+
+    def square_free_decomposition(self):
+        """
+        Returns the square-free decomposition of self (a partial
+        factorization into square-free, relatively prime polynomials)
+        as a list of 2-tuples, where the first element in each tuple
+        is a factor, and the second is its exponent.
+        Assumes that self is primitive.
+
+        EXAMPLES:
+            sage: f = ntl.ZZX([0, 1, 2, 1])
+            sage: f.square_free_decomposition()
+            [([0 1], 1), ([1 1], 2)]
+        """
+        cdef ZZX_c** v
+        cdef long* e
+        cdef long i, n
+        _sig_on
+        ZZX_square_free_decomposition(&v, &e, &n, self.x)
+        _sig_off
+        F = []
+        for i from 0 <= i < n:
+            F.append((make_ZZX(v[i]), e[i]))
+        free(v)
+        free(e)
+        return F
+
+    cdef set(self, void* x):  # only used internally for initialization; assumes self.x not set yet!
+        self.x = <ZZX_c*>x
+    
+cdef make_ZZX(ZZX_c* x):
+    cdef ntl_ZZX y
+    _sig_off
+    y = ntl_ZZX()
+    y.x = x
+    return y
+
+def make_new_ZZX(v=[]):
+    cdef Py_ssize_t i
+    if PY_TYPE_CHECK(v, list):
+        for i from 0 <= i < len(v):
+            x = v[i]
+            if not PY_TYPE_CHECK(x, Integer) and not PY_TYPE_CHECK(x, int):
+                v[i] = Integer(x)
+    s = str(v).replace(',',' ')
+    cdef ntl_ZZX z
+    z = ntl_ZZX()
+    _sig_on
+    z.x = str_to_ZZX(s)
+    _sig_off
+    return z
+
+one_ZZX = make_new_ZZX([1])
+zero_ZZX = make_new_ZZX()
+
+##############################################################################
+#
+# ZZ_p_c: integers modulo p
+#
+##############################################################################
+cdef class ntl_ZZ_p:
+    r"""
+    The \class{ZZ_p_c} class is used to represent integers modulo $p$.
+    The modulus $p$ may be any positive integer, not necessarily prime.
+    
+    Objects of the class \class{ZZ_p_c} are represented as a \code{ZZ} in the
+    range $0, \ldots, p-1$.
+
+    An executing program maintains a "current modulus", which is set to p
+    with ntl_ZZ_p.init(p).  The current modulus should be initialized before
+    any ZZ_p_c objects are created.
+
+    The modulus may be changed, and a mechanism is provided for saving and
+    restoring a modulus (see classes ZZ_pBak and ZZ_pContext below).
+
+    TODO: This documentation is wrong
+    """
+    # See ntl.pxd for definition of data members
+
+    def __reduce__(self):
+        raise NotImplementedError
+
+    def __dealloc__(self):
+        del_ZZ_p(self.x)
+
+    def __repr__(self):
+        _sig_on
+        return string_delete(ZZ_p_to_str(self.x))
+
+    def __cmp__(ntl_ZZ_p self, ntl_ZZ_p other):
+        cdef int t
+        _sig_on
+        t = ZZ_p_eq(self.x, other.x)
+        _sig_off
+        if t:
+            return 0
+        return 1
+
+    def __invert__(ntl_ZZ_p self):
+        _sig_on
+        return make_ZZ_p(ZZ_p_inv(self.x))
+        
+
+    def __mul__(ntl_ZZ_p self, other):
+        cdef ntl_ZZ_p y
+        if not isinstance(other, ntl_ZZ_p):
+            other = ntl_ZZ_p(other)
+        y = other
+        _sig_on
+        return make_ZZ_p(ZZ_p_mul(self.x, y.x))
+            
+    def __sub__(ntl_ZZ_p self, other):
+        cdef ntl_ZZ_p y
+        if not isinstance(other, ntl_ZZ_p):
+            other = ntl_ZZ_p(other)
+        y = other
+        _sig_on
+        return make_ZZ_p(ZZ_p_sub(self.x, y.x))
+
+    def __add__(ntl_ZZ_p self, other):
+        cdef ntl_ZZ_p y
+        if not isinstance(other, ntl_ZZ_p):
+            other = ntl_ZZ_p(other)
+        y = other
+        _sig_on
+        return make_ZZ_p(ZZ_p_add(self.x, y.x))
+
+    def __neg__(ntl_ZZ_p self):
+        _sig_on
+        return make_ZZ_p(ZZ_p_neg(self.x))
+            
+    def __pow__(ntl_ZZ_p self, long e, ignored):
+        _sig_on
+        return make_ZZ_p(ZZ_p_pow(self.x, e))
+
+    cdef set(self, void *y):  # only used internally for initialization; assumes self.x not set yet!
+        self.x = <ZZ_p_c*> y
+        
+    cdef int get_as_int(ntl_ZZ_p self):
+        r"""
+        Returns value as C int.
+        Return value is only valid if the result fits into an int.
+
+        AUTHOR: David Harvey (2006-08-05)
+        """
+        return ZZ_p_to_int(self.x)
+
+    def get_as_int_doctest(self):
+        r"""
+        This method exists solely for automated testing of get_as_int().
+
+        sage: ntl.set_modulus(ntl.ZZ(20)) 
+        sage: x = ntl.ZZ_p(42)
+        sage: i = x.get_as_int_doctest()
+        sage: print i
+         2
+        sage: print type(i)
+         <type 'int'>
+        """
+        return self.get_as_int()
+
+    cdef void set_from_int(ntl_ZZ_p self, int value):
+        r"""
+        Sets the value from a C int.
+
+        AUTHOR: David Harvey (2006-08-05)
+        """
+        ZZ_p_set_from_int(self.x, value)
+
+    def set_from_int_doctest(self, value):
+        r"""
+        This method exists solely for automated testing of set_from_int().
+
+        sage: ntl.set_modulus(ntl.ZZ(20)) 
+        sage: x = ntl.ZZ_p()
+        sage: x.set_from_int_doctest(42)
+        sage: x
+         2
+        """
+        self.set_from_int(int(value))
+
+    # todo: add wrapper for int_to_ZZ_p in wrap.cc?
+
+        
+cdef public make_ZZ_p(ZZ_p_c* x):
+    cdef ntl_ZZ_p y
+    _sig_off
+    y = ntl_ZZ_p()
+    y.x = x
+    return y
+
+def make_new_ZZ_p(x='0'):
+    s = str(x)
+    cdef ntl_ZZ_p n
+    n = ntl_ZZ_p()
+    _sig_on
+    n.x = str_to_ZZ_p(s)
+    _sig_off
+    return n
+
+def set_ZZ_p_modulus(ntl_ZZ p):
+    ntl_ZZ_set_modulus(<ZZ_c*>p.x)
+
+       
+def ntl_ZZ_p_random():
+    """
+    Return a random number modulo p.
+    """
+    _sig_on
+    return make_ZZ_p(ZZ_p_random())
+
+##############################################################################
+#
+# ZZ_pX_c  -- polynomials over the integers modulo p
+#
+##############################################################################
+
+cdef class ntl_ZZ_pX:
+    r"""
+    The class \class{ZZ_pX_c} implements polynomial arithmetic modulo $p$.
+
+    Polynomial arithmetic is implemented using the FFT, combined with
+    the Chinese Remainder Theorem.  A more detailed description of the
+    techniques used here can be found in [Shoup, J. Symbolic
+    Comp. 20:363-397, 1995].
+
+    Small degree polynomials are multiplied either with classical 
+    or Karatsuba algorithms.
+    """
+    # See ntl_ZZ_pX.pxd for definition of data members
+    def __init__(self):
+        """
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20)) 
+            sage: f = ntl.ZZ_pX([1,2,5,-9])
+            sage: f
+            [1 2 5 11]
+            sage: g = ntl.ZZ_pX([0,0,0]); g
+            []
+            sage: g[10]=5
+            sage: g
+            [0 0 0 0 0 0 0 0 0 0 5]
+            sage: g[10]
+            5
+        """
+        return 
+
+    def __reduce__(self):
+        raise NotImplementedError
+
+    def __dealloc__(self):
+        if self.x:
+            ZZ_pX_dealloc(self.x)
+                
+
+    def __repr__(self):
+        _sig_on
+        return string_delete(ZZ_pX_repr(self.x))
+
+    def __copy__(self):
+        return make_ZZ_pX(ZZ_pX_copy(self.x))
+
+    def copy(self):
+        return make_ZZ_pX(ZZ_pX_copy(self.x))
+
+    cdef set(self, void* x):  # only used internally for initialization; assumes self.x not set yet!
+        self.x = <ZZ_pX_c*>x
+
+    def __setitem__(self, long i, a):
+        if i < 0:
+            raise IndexError, "index (i=%s) must be >= 0"%i
+        a = str(int(a))
+        ZZ_pX_setitem(self.x, i, a)
+
+    cdef void setitem_from_int(ntl_ZZ_pX self, long i, int value):
+        r"""
+        Sets ith coefficient to value.
+
+        AUTHOR: David Harvey (2006-08-05)
+        """        
+        ZZ_pX_setitem_from_int(self.x, i, value)
+
+    def setitem_from_int_doctest(self, i, value):
+        r"""
+        This method exists solely for automated testing of setitem_from_int().
+
+        sage: ntl.set_modulus(ntl.ZZ(20)) 
+        sage: x = ntl.ZZ_pX([2, 3, 4])
+        sage: x.setitem_from_int_doctest(5, 42)
+        sage: x
+         [2 3 4 0 0 2]
+        """
+        self.setitem_from_int(int(i), int(value))
+
+    def __getitem__(self, unsigned int i):
+        cdef char* t
+        t = ZZ_pX_getitem(self.x,i)
+        return int(string(t))
+
+    cdef int getitem_as_int(ntl_ZZ_pX self, long i):
+        r"""
+        Returns ith coefficient as C int.
+        Return value is only valid if the result fits into an int.
+
+        AUTHOR: David Harvey (2006-08-05)
+        """        
+        return ZZ_pX_getitem_as_int(self.x, i)
+
+    def getitem_as_int_doctest(self, i):
+        r"""
+        This method exists solely for automated testing of getitem_as_int().
+
+        sage: ntl.set_modulus(ntl.ZZ(20)) 
+        sage: x = ntl.ZZ_pX([2, 3, 5, -7, 11])
+        sage: i = x.getitem_as_int_doctest(3)
+        sage: print i
+         13
+        sage: print type(i)
+         <type 'int'>
+        sage: print x.getitem_as_int_doctest(15)
+         0
+        """
+        return self.getitem_as_int(i)
+
+    def list(self):
+        """
+        Return list of entries as a list of Python int's.
+        """
+        return eval(str(self).replace(' ',','))
+
+    def __add__(ntl_ZZ_pX self, ntl_ZZ_pX other):
+        """
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))         
+            sage: ntl.ZZ_pX(range(5)) + ntl.ZZ_pX(range(6))
+            [0 2 4 6 8 5]
+        """
+        return make_ZZ_pX(ZZ_pX_add(self.x, other.x))
+
+    def __sub__(ntl_ZZ_pX self, ntl_ZZ_pX other):
+        """
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))         
+            sage: ntl.ZZ_pX(range(5)) - ntl.ZZ_pX(range(6))
+            [0 0 0 0 0 15]
+        """
+        return make_ZZ_pX(ZZ_pX_sub(self.x, other.x))
+
+    def __mul__(ntl_ZZ_pX self, ntl_ZZ_pX other):
+        """
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))         
+            sage: ntl.ZZ_pX(range(5)) * ntl.ZZ_pX(range(6))
+            [0 0 1 4 10 0 10 14 11]
+        """
+        _sig_on
+        return make_ZZ_pX(ZZ_pX_mul(self.x, other.x))
+
+    def __div__(ntl_ZZ_pX self, ntl_ZZ_pX other):
+        """
+        Compute quotient self / other, if the quotient is a polynomial.
+        Otherwise an Exception is raised.
+        
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(17))         
+            sage: f = ntl.ZZ_pX([1,2,3]) * ntl.ZZ_pX([4,5])**2
+            sage: g = ntl.ZZ_pX([4,5])
+            sage: f/g
+            [4 13 5 15]
+            sage: ntl.ZZ_pX([1,2,3]) * ntl.ZZ_pX([4,5])
+            [4 13 5 15]
+
+            sage: f = ntl.ZZ_pX(range(10)); g = ntl.ZZ_pX([-1,0,1])
+            sage: f/g
+            Traceback (most recent call last):
+            ...
+            ArithmeticError: self (=[0 1 2 3 4 5 6 7 8 9]) is not divisible by other (=[16 0 1])
+        """
+        _sig_on
+        cdef int divisible
+        cdef ZZ_pX_c* q
+        q = ZZ_pX_div(self.x, other.x, &divisible)
+        if not divisible:
+            raise ArithmeticError, "self (=%s) is not divisible by other (=%s)"%(self, other)
+        return make_ZZ_pX(q)
+
+    def __mod__(ntl_ZZ_pX self, ntl_ZZ_pX other):
+        """
+        Given polynomials a, b in ZZ[X], there exist polynomials q, r
+        in QQ[X] such that a = b*q + r, deg(r) < deg(b).  This
+        function returns q if q lies in ZZ[X], and otherwise raises an
+        Exception.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(17))         
+            sage: f = ntl.ZZ_pX([2,4,6]); g = ntl.ZZ_pX([2])
+            sage: f % g   # 0
+            []
+
+            sage: f = ntl.ZZ_pX(range(10)); g = ntl.ZZ_pX([-1,0,1])
+            sage: f % g
+            [3 8]
+        """
+        _sig_on
+        return make_ZZ_pX(ZZ_pX_mod(self.x, other.x))
+
+    def quo_rem(self, ntl_ZZ_pX other):
+        """
+        Returns the unique integral q and r such that self = q*other +
+        r, if they exist.  Otherwise raises an Exception.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(17))         
+            sage: f = ntl.ZZ_pX(range(10)); g = ntl.ZZ_pX([-1,0,1])
+            sage: q, r = f.quo_rem(g)
+            sage: q, r
+            ([3 7 1 4 14 16 8 9], [3 8])
+            sage: q*g + r == f
+            True
+        """
+        cdef ZZ_pX_c *r, *q
+        _sig_on
+        ZZ_pX_quo_rem(self.x, other.x, &r, &q)
+        return (make_ZZ_pX(q), make_ZZ_pX(r))
+
+    def square(self):
+        """
+        Return f*f.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(17))
+            sage: f = ntl.ZZ_pX([-1,0,1])
+            sage: f*f
+            [1 0 15 0 1]
+        """
+        _sig_on
+        return make_ZZ_pX(ZZ_pX_square(self.x))
+
+    def __pow__(ntl_ZZ_pX self, long n, ignored):
+        """
+        Return the n-th nonnegative power of self.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))
+            sage: g = ntl.ZZ_pX([-1,0,1])
+            sage: g**10
+            [1 0 10 0 5 0 0 0 10 0 8 0 10 0 0 0 5 0 10 0 1]
+        """
+        if n < 0:
+            raise NotImplementedError
+        import sage.rings.arith
+        return sage.rings.arith.generic_power(self, n, make_new_ZZ_pX([1]))
+
+    def __cmp__(ntl_ZZ_pX self, ntl_ZZ_pX other):
+        """
+        Decide whether or not self and other are equal.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: f = ntl.ZZ_pX([1,2,3])
+            sage: g = ntl.ZZ_pX([1,2,3,0])
+            sage: f == g
+            True
+            sage: g = ntl.ZZ_pX([0,1,2,3])
+            sage: f == g
+            False
+        """
+        if ZZ_pX_equal(self.x, other.x):
+            return 0
+        return -1
+
+    def is_zero(self):
+        """
+        Return True exactly if this polynomial is 0.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: f = ntl.ZZ_pX([0,0,0,20])
+            sage: f.is_zero()
+            True
+            sage: f = ntl.ZZ_pX([0,0,1])
+            sage: f
+            [0 0 1]
+            sage: f.is_zero()
+            False
+        """
+        return bool(ZZ_pX_is_zero(self.x))
+
+    def is_one(self):
+        """
+        Return True exactly if this polynomial is 1.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: f = ntl.ZZ_pX([1,1])
+            sage: f.is_one()
+            False
+            sage: f = ntl.ZZ_pX([1])
+            sage: f.is_one()
+            True
+        """
+        return bool(ZZ_pX_is_one(self.x))
+
+    def is_monic(self):
+        """
+        Return True exactly if this polynomial is monic.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: f = ntl.ZZ_pX([2,0,0,1])
+            sage: f.is_monic()
+            True
+            sage: g = f.reverse()
+            sage: g.is_monic()
+            False
+            sage: g
+            [1 0 0 2]
+            sage: f = ntl.ZZ_pX([1,2,0,3,0,2])
+            sage: f.is_monic()
+            False            
+        """
+        # The following line is what we should have.  However, strangely this is *broken* 
+        # on PowerPC Intel in NTL, so we program around
+        # the problem.  (William Stein)
+        #return bool(ZZ_pX_is_monic(self.x))
+
+        if ZZ_pX_is_zero(self.x):
+             return False
+        return bool(ZZ_p_is_one(ZZ_pX_leading_coefficient(self.x)))
+
+    def __neg__(self):
+        """
+        Return the negative of self.
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))
+            sage: f = ntl.ZZ_pX([2,0,0,1])
+            sage: -f
+            [18 0 0 19]
+        """
+        return make_ZZ_pX(ZZ_pX_neg(self.x))
+
+    def left_shift(self, long n):
+        """
+        Return the polynomial obtained by shifting all coefficients of
+        this polynomial to the left n positions.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: f = ntl.ZZ_pX([2,0,0,1])
+            sage: f
+            [2 0 0 1]
+            sage: f.left_shift(2)
+            [0 0 2 0 0 1]
+            sage: f.left_shift(5)
+            [0 0 0 0 0 2 0 0 1]
+
+        A negative left shift is a right shift.
+            sage: f.left_shift(-2)
+            [0 1]
+        """
+        return make_ZZ_pX(ZZ_pX_left_shift(self.x, n))
+        
+    def right_shift(self, long n):
+        """
+        Return the polynomial obtained by shifting all coefficients of
+        this polynomial to the right n positions.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: f = ntl.ZZ_pX([2,0,0,1])
+            sage: f
+            [2 0 0 1]
+            sage: f.right_shift(2)
+            [0 1]
+            sage: f.right_shift(5)
+            []
+            sage: f.right_shift(-2)
+            [0 0 2 0 0 1]
+        """
+        return make_ZZ_pX(ZZ_pX_right_shift(self.x, n))
+
+    def gcd(self, ntl_ZZ_pX other):
+        """
+        Return the gcd d = gcd(a, b), where by convention the leading coefficient
+        of d is >= 0.  We uses a multi-modular algorithm.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(17))        
+            sage: f = ntl.ZZ_pX([1,2,3]) * ntl.ZZ_pX([4,5])**2
+            sage: g = ntl.ZZ_pX([1,1,1])**3 * ntl.ZZ_pX([1,2,3])
+            sage: f.gcd(g)
+            [6 12 1]
+            sage: g.gcd(f)
+            [6 12 1]
+        """
+        _sig_on
+        return make_ZZ_pX(ZZ_pX_gcd(self.x, other.x))
+
+    def xgcd(self, ntl_ZZ_pX other, plain=True):
+        """
+        Returns r,s,t such that r = s*self + t*other.
+            
+        Here r is the resultant of a and b; if r != 0, then this
+        function computes s and t such that: a*s + b*t = r; otherwise
+        s and t are both 0. 
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(17))                
+            sage: f = ntl.ZZ_pX([1,2,3]) * ntl.ZZ_pX([4,5])**2
+            sage: g = ntl.ZZ_pX([1,1,1])**3 * ntl.ZZ_pX([1,2,3])
+            sage: f.xgcd(g)   # nothing since they are not coprime
+            ([6 12 1], [15 13 6 8 7 9], [4 13])
+    
+        In this example the input quadratic polynomials have a common root modulo 13.
+            sage: f = ntl.ZZ_pX([5,0,1])
+            sage: g = ntl.ZZ_pX([18,0,1])
+            sage: f.xgcd(g)
+            ([1], [13], [4])
+            """
+        cdef ZZ_pX_c *s, *t, *r
+        _sig_on
+        if plain:
+            ZZ_pX_plain_xgcd(&r, &s, &t, self.x, other.x)
+        else:
+            ZZ_pX_xgcd(&r, &s, &t, self.x, other.x)            
+        return (make_ZZ_pX(r), make_ZZ_pX(s), make_ZZ_pX(t))
+
+    def degree(self):
+        """
+        Return the degree of this polynomial.  The degree of the 0
+        polynomial is -1.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))                
+            sage: f = ntl.ZZ_pX([5,0,1])
+            sage: f.degree()
+            2
+            sage: f = ntl.ZZ_pX(range(100))
+            sage: f.degree()
+            99
+            sage: f = ntl.ZZ_pX()
+            sage: f.degree()
+            -1
+            sage: f = ntl.ZZ_pX([1])
+            sage: f.degree()
+            0
+        """
+        return ZZ_pX_degree(self.x)
+
+    def leading_coefficient(self):
+        """
+        Return the leading coefficient of this polynomial.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))                
+            sage: f = ntl.ZZ_pX([3,6,9])
+            sage: f.leading_coefficient()
+            9
+            sage: f = ntl.ZZ_pX()
+            sage: f.leading_coefficient()
+            0
+        """
+        return make_ZZ_p(ZZ_pX_leading_coefficient(self.x))
+
+    def constant_term(self):
+        """
+        Return the constant coefficient of this polynomial.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: f = ntl.ZZ_pX([3,6,9])
+            sage: f.constant_term()
+            3
+            sage: f = ntl.ZZ_pX()
+            sage: f.constant_term()
+            0
+        """
+        cdef char* t
+        t = ZZ_pX_constant_term(self.x)
+        return int(string(t))
+
+    def set_x(self):
+        """
+        Set this polynomial to the monomial "x".
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))                
+            sage: f = ntl.ZZ_pX()
+            sage: f.set_x()
+            sage: f
+            [0 1]
+            sage: g = ntl.ZZ_pX([0,1])
+            sage: f == g
+            True
+
+        Though f and g are equal, they are not the same objects in memory:
+            sage: f is g
+            False
+            
+        """
+        ZZ_pX_set_x(self.x)
+
+    def is_x(self):
+        """
+        True if this is the polynomial "x".
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: f = ntl.ZZ_pX()
+            sage: f.set_x()
+            sage: f.is_x()
+            True
+            sage: f = ntl.ZZ_pX([0,1])
+            sage: f.is_x()
+            True
+            sage: f = ntl.ZZ_pX([1])
+            sage: f.is_x()
+            False
+        """
+        return bool(ZZ_pX_is_x(self.x))
+
+    def derivative(self):
+        """
+        Return the derivative of this polynomial.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: f = ntl.ZZ_pX([1,7,0,13])
+            sage: f.derivative()
+            [7 0 19]
+        """
+        return make_ZZ_pX(ZZ_pX_derivative(self.x))
+
+    def factor(self, verbose=False):
+        cdef ZZ_pX_c** v
+        cdef long* e
+        cdef long i, n
+        _sig_on
+        ZZ_pX_factor(&v, &e, &n, self.x, verbose)
+        _sig_off
+        F = []
+        for i from 0 <= i < n:
+            F.append((make_ZZ_pX(v[i]), e[i]))
+        free(v)
+        free(e)
+        return F
+
+    def linear_roots(self):
+        """
+        Assumes that input is monic, and has deg(f) distinct roots.
+        Returns the list of roots.
+        """
+        cdef ZZ_p_c** v
+        cdef long i, n
+        _sig_on
+        ZZ_pX_linear_roots(&v, &n, self.x)
+        _sig_off
+        F = []
+        for i from 0 <= i < n:
+            F.append(make_ZZ_p(v[i]))
+        free(v)
+        return F
+
+    def reverse(self, hi=None):
+        """
+        Return the polynomial obtained by reversing the coefficients
+        of this polynomial.  If hi is set then this function behaves
+        as if this polynomial has degree hi.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))                
+            sage: f = ntl.ZZ_pX([1,2,3,4,5])
+            sage: f.reverse()
+            [5 4 3 2 1]
+            sage: f.reverse(hi=10)
+            [0 0 0 0 0 0 5 4 3 2 1]
+            sage: f.reverse(hi=2)
+            [3 2 1]
+            sage: f.reverse(hi=-2)
+            []
+        """
+        if not (hi is None):
+            return make_ZZ_pX(ZZ_pX_reverse_hi(self.x, int(hi)))
+        else:
+            return make_ZZ_pX(ZZ_pX_reverse(self.x))
+
+    def truncate(self, long m):
+        """
+        Return the truncation of this polynomial obtained by
+        removing all terms of degree >= m.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))                
+            sage: f = ntl.ZZ_pX([1,2,3,4,5])
+            sage: f.truncate(3)
+            [1 2 3]
+            sage: f.truncate(8)
+            [1 2 3 4 5]
+            sage: f.truncate(1)
+            [1]
+            sage: f.truncate(0)
+            []
+            sage: f.truncate(-1)
+            []
+            sage: f.truncate(-5)
+            []
+        """
+        if m <= 0:
+            return make_new_ZZ_pX()
+        return make_ZZ_pX(ZZ_pX_truncate(self.x, m))
+
+    def multiply_and_truncate(self, ntl_ZZ_pX other, long m):
+        """
+        Return self*other but with terms of degree >= m removed.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: f = ntl.ZZ_pX([1,2,3,4,5])
+            sage: g = ntl.ZZ_pX([10])
+            sage: f.multiply_and_truncate(g, 2)
+            [10]
+            sage: g.multiply_and_truncate(f, 2)
+            [10]
+        """
+        if m <= 0:
+            return make_new_ZZ_pX()
+        return make_ZZ_pX(ZZ_pX_multiply_and_truncate(self.x, other.x, m))
+
+    def square_and_truncate(self, long m):
+        """
+        Return self*self but with terms of degree >= m removed.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: f = ntl.ZZ_pX([1,2,3,4,5])
+            sage: f.square_and_truncate(4)
+            [1 4 10]
+            sage: (f*f).truncate(4)
+            [1 4 10]
+        """
+        if m < 0:
+            return make_new_ZZ_pX()
+        return make_ZZ_pX(ZZ_pX_square_and_truncate(self.x, m))
+
+    def invert_and_truncate(self, long m):
+        """
+        Compute and return the inverse of self modulo $x^m$.
+        The constant term of self must be 1 or -1.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: f = ntl.ZZ_pX([1,2,3,4,5,6,7])
+            sage: f.invert_and_truncate(20)
+            [1 18 1 0 0 0 0 8 17 2 13 0 0 0 4 0 17 10 9]
+            sage: g = f.invert_and_truncate(20)
+            sage: g * f
+            [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 4 4 3]
+        """
+        if m < 0:
+            raise ArithmeticError, "m (=%s) must be positive"%m
+        n = self.constant_term()
+        if n != 1 and n != -1:
+            raise ArithmeticError, \
+                  "The constant term of self must be 1 or -1."
+        _sig_on        
+        return make_ZZ_pX(ZZ_pX_invert_and_truncate(self.x, m))
+        
+    def multiply_mod(self, ntl_ZZ_pX other, ntl_ZZ_pX modulus):
+        """
+        Return self*other % modulus.  The modulus must be monic with
+        deg(modulus) > 0, and self and other must have smaller degree.
+        
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))        
+            sage: modulus = ntl.ZZ_pX([1,2,0,1])    # must be monic
+            sage: g = ntl.ZZ_pX([-1,0,1])
+            sage: h = ntl.ZZ_pX([3,7,13])
+            sage: h.multiply_mod(g, modulus)
+            [10 6 4]
+        """
+        _sig_on
+        return make_ZZ_pX(ZZ_pX_multiply_mod(self.x, other.x, modulus.x))
+
+    def trace_mod(self, ntl_ZZ_pX modulus):
+        """
+        Return the trace of this polynomial modulus the modulus.
+        The modulus must be monic, and of positive degree degree bigger
+        than the the degree of self.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))                
+            sage: f = ntl.ZZ_pX([1,2,0,3])
+            sage: mod = ntl.ZZ_pX([5,3,-1,1,1])
+            sage: f.trace_mod(mod)
+            3
+        """
+        _sig_on
+        return make_ZZ_p(ZZ_pX_trace_mod(self.x, modulus.x))
+
+    def trace_list(self):
+        """
+        Return the list of traces of the powers $x^i$ of the
+        monomial x modulo this polynomial for i = 0, ..., deg(f)-1.
+        This polynomial must be monic.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(20))                
+            sage: f = ntl.ZZ_pX([1,2,0,3,0,1])
+            sage: f.trace_list()
+            [5, 0, 14, 0, 10]
+
+        The input polynomial must be monic or a ValueError is raised:
+            sage: ntl.set_modulus(ntl.ZZ(20))                
+            sage: f = ntl.ZZ_pX([1,2,0,3,0,2])
+            sage: f.trace_list()
+            Traceback (most recent call last):
+            ...
+            ValueError: polynomial must be monic.
+        """
+        if not self.is_monic():
+            raise ValueError, "polynomial must be monic."
+        _sig_on
+        cdef char* t
+        t = ZZ_pX_trace_list(self.x)
+        return eval(string(t).replace(' ', ','))
+
+    def resultant(self, ntl_ZZ_pX other):
+        """
+        Return the resultant of self and other.
+        
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(17))                
+            sage: f = ntl.ZZ_pX([17,0,1,1])
+            sage: g = ntl.ZZ_pX([34,-17,18,2])
+            sage: f.resultant(g)
+            0
+        """
+        _sig_on
+        return make_ZZ_p(ZZ_pX_resultant(self.x, other.x))
+
+    def norm_mod(self, ntl_ZZ_pX modulus):
+        """
+        Return the norm of this polynomial modulo the modulus.  The
+        modulus must be monic, and of positive degree strictly greater
+        than the degree of self. 
+
+
+        EXAMPLE:
+            sage: ntl.set_modulus(ntl.ZZ(17))                
+            sage: f = ntl.ZZ_pX([1,2,0,3])
+            sage: mod = ntl.ZZ_pX([-5,2,0,0,1])
+            sage: f.norm_mod(mod)
+            11
+
+        The norm is the constant term of the characteristic polynomial.
+            sage: f.charpoly_mod(mod)
+            [11 1 8 14 1]
+        """
+        _sig_on
+        return make_ZZ_p(ZZ_pX_norm_mod(self.x, modulus.x))
+
+    def discriminant(self):
+        r"""
+        Return the discriminant of a=self, which is by definition
+        $$
+                (-1)^{m(m-1)/2} {\mbox{\tt resultant}}(a, a')/lc(a),
+        $$      
+        where m = deg(a), and lc(a) is the leading coefficient of a.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(17))                
+            sage: f = ntl.ZZ_pX([1,2,0,3])
+            sage: f.discriminant()
+            1
+        """
+        cdef long m
+        
+        c = ~self.leading_coefficient()
+        m = self.degree()
+        if (m*(m-1)/2) % 2:
+            c = -c
+        return c*self.resultant(self.derivative())
+
+    def charpoly_mod(self, ntl_ZZ_pX modulus):
+        """
+        Return the characteristic polynomial of this polynomial modulo
+        the modulus.  The modulus must be monic of degree bigger than
+        self.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(17))                
+            sage: f = ntl.ZZ_pX([1,2,0,3])
+            sage: mod = ntl.ZZ_pX([-5,2,0,0,1])
+            sage: f.charpoly_mod(mod)
+            [11 1 8 14 1]
+        """
+        _sig_on
+        return make_ZZ_pX(ZZ_pX_charpoly_mod(self.x, modulus.x))
+
+    def minpoly_mod(self, ntl_ZZ_pX modulus):
+        """
+        Return the minimal polynomial of this polynomial modulo the
+        modulus.  The modulus must be monic of degree bigger than
+        self.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(17))
+            sage: f = ntl.ZZ_pX([0,0,1])
+            sage: g = f*f
+            sage: f.charpoly_mod(g)
+            [0 0 0 0 1]
+
+        However, since $f^2 = 0$ moduluo $g$, its minimal polynomial
+        is of degree $2$.
+            sage: f.minpoly_mod(g)
+            [0 0 1]
+        """
+        _sig_on
+        return make_ZZ_pX(ZZ_pX_minpoly_mod(self.x, modulus.x))
+
+    def clear(self):
+        """
+        Reset this polynomial to 0.  Changes this polynomial in place.
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(17))        
+            sage: f = ntl.ZZ_pX([1,2,3])
+            sage: f
+            [1 2 3]
+            sage: f.clear()
+            sage: f
+            []
+        """
+        ZZ_pX_clear(self.x)
+
+    def preallocate_space(self, long n):
+        """
+        Pre-allocate spaces for n coefficients.  The polynomial that f
+        represents is unchanged.  This is useful if you know you'll be
+        setting coefficients up to n, so memory isn't re-allocated as
+        the polynomial grows.  (You might save a millisecond with this
+        function.)
+
+        EXAMPLES:
+            sage: ntl.set_modulus(ntl.ZZ(17))        
+            sage: f = ntl.ZZ_pX([1,2,3])
+            sage: f.preallocate_space(20)
+            sage: f
+            [1 2 3]
+            sage: f[10]=5  # no new memory is allocated
+            sage: f
+            [1 2 3 0 0 0 0 0 0 0 5]
+        """
+        _sig_on
+        ZZ_pX_preallocate_space(self.x, n)
+        _sig_off
+
+
+## TODO: NTL's ZZ_pX_c has minpolys of linear recurrence sequences!!!
+
+    
+cdef make_ZZ_pX(ZZ_pX_c* x):
+    cdef ntl_ZZ_pX y
+    _sig_off
+    y = ntl_ZZ_pX()
+    y.x = x
+    return y
+
+def make_new_ZZ_pX(v=[]):
+    from sage.rings.integer_mod import IntegerMod_abstract
+    cdef Py_ssize_t i
+    if PY_TYPE_CHECK(v, list):
+        for i from 0 <= i < len(v):
+            x = v[i]
+            if not PY_TYPE_CHECK(x, IntegerMod_abstract) and not PY_TYPE_CHECK(x, Integer) and not PY_TYPE_CHECK(x, int):
+                v[i] = Integer(x)
+    s = str(v).replace(',',' ').replace('L','')
+    cdef ntl_ZZ_pX z
+    z = ntl_ZZ_pX()
+    _sig_on
+    z.x = str_to_ZZ_pX(s)
+    _sig_off
+    return z
+
+
+##############################################################################
+#
+# ntl_mat_ZZ: Matrices over the integers via NTL
+#
+##############################################################################
+
+cdef class ntl_mat_ZZ:
+    # see ntl.pxd for data members
+    r"""
+    The \class{mat_ZZ_c} class implements arithmetic with matrices over $\Z$.
+    """
+    def __init__(self, nrows=0,  ncols=0, v=None):
+        if nrows == _INIT:
+            return
+        cdef unsigned long i, j
+        cdef ntl_ZZ tmp
+        if nrows == 0 and ncols == 0:
+            return
+        nrows = int(nrows)
+        ncols = int(ncols)
+        self.x = new_mat_ZZ(nrows, ncols)
+        self.__nrows = nrows
+        self.__ncols = ncols
+        if v != None:
+            for i from 0 <= i < nrows:
+                for j from 0 <= j < ncols:
+                    tmp = make_new_ZZ(v[i*ncols+j])
+                    mat_ZZ_setitem(self.x, i, j, <ZZ_c*> tmp.x)
+            
+
+    def __reduce__(self):
+        raise NotImplementedError
+
+    def __dealloc__(self):
+        del_mat_ZZ(self.x)
+
+    def __repr__(self):
+        _sig_on
+        return string_delete(mat_ZZ_to_str(self.x))
+
+    def __mul__(ntl_mat_ZZ self, other):
+        cdef ntl_mat_ZZ y
+        if not isinstance(other, ntl_mat_ZZ):
+            other = ntl_mat_ZZ(other)
+        y = other
+        _sig_on
+        return make_mat_ZZ(mat_ZZ_mul(self.x, y.x))
+            
+    def __sub__(ntl_mat_ZZ self, other):
+        cdef ntl_mat_ZZ y
+        if not isinstance(other, ntl_mat_ZZ):
+            other = ntl_mat_ZZ(other)
+        y = other
+        _sig_on
+        return make_mat_ZZ(mat_ZZ_sub(self.x, y.x))
+
+    def __add__(ntl_mat_ZZ self, other):
+        cdef ntl_mat_ZZ y
+        if not isinstance(other, ntl_mat_ZZ):
+            other = ntl_mat_ZZ(other)
+        y = other
+        _sig_on
+        return make_mat_ZZ(mat_ZZ_add(self.x, y.x))
+            
+    def __pow__(ntl_mat_ZZ self, long e, ignored):
+        _sig_on
+        return make_mat_ZZ(mat_ZZ_pow(self.x, e))
+
+    def nrows(self):
+        return self.__nrows
+    
+    def ncols(self):
+        return self.__ncols
+
+    def __setitem__(self, ij, x):
+        cdef ntl_ZZ y
+        cdef int i, j
+        if not isinstance(x, ntl_ZZ):
+            y = make_new_ZZ(x)
+        else:
+            y = x
+        if not isinstance(ij, tuple) or len(ij) != 2:
+            raise TypeError, 'ij must be a 2-tuple'
+        i, j = int(ij[0]),int(ij[1])
+        if i < 0 or i >= self.__nrows or j < 0 or j >= self.__ncols:
+            raise IndexError, "array index out of range"
+        _sig_on
+        mat_ZZ_setitem(self.x, i, j, <ZZ_c*> y.x)
+        _sig_off
+
+    def __getitem__(self, ij):
+        cdef int i, j
+        if not isinstance(ij, tuple) or len(ij) != 2:
+            raise TypeError, 'ij must be a 2-tuple'
+        i, j = ij
+        if i < 0 or i >= self.__nrows or j < 0 or j >= self.__ncols:
+            raise IndexError, "array index out of range"
+        return make_ZZ(mat_ZZ_getitem(self.x, i+1, j+1))
+
+    def determinant(self, deterministic=True):
+        _sig_on
+        return make_ZZ(mat_ZZ_determinant(self.x, deterministic))
+
+    def HNF(self, D=None):
+        r"""
+        The input matrix A=self is an n x m matrix of rank m (so n >=
+        m), and D is a multiple of the determinant of the lattice L
+        spanned by the rows of A.  The output W is the Hermite Normal
+        Form of A; that is, W is the unique m x m matrix whose rows
+        span L, such that
+    
+        - W is lower triangular,
+        - the diagonal entries are positive,
+        - any entry below the diagonal is a non-negative number
+          strictly less than the diagonal entry in its column.
+    
+        This is implemented using the algorithm of [P. Domich,
+        R. Kannan and L. Trotter, Math. Oper. Research 12:50-59,
+        1987].
+
+        TIMINGS:
+        NTL isn't very good compared to MAGMA, unfortunately:
+        
+            sage.: import ntl
+            sage.: a=MatrixSpace(Q,200).random_element()    # -2 to 2
+            sage.: A=ntl.mat_ZZ(200,200)
+            sage.: for i in xrange(a.nrows()):
+               ....:     for j in xrange(a.ncols()):
+               ....:         A[i,j] = a[i,j]
+               ....:
+            sage.: time d=A.determinant()
+            Time.: 3.89 seconds
+            sage.: time B=A.HNF(d)
+            Time.: 27.59 seconds
+
+        In comparison, MAGMA does this much more quickly:
+        \begin{verbatim}
+            > A := MatrixAlgebra(Z,200)![Random(-2,2) : i in [1..200^2]];
+            > time d := Determinant(A);
+            Time: 0.710
+            > time H := HermiteForm(A);
+            Time: 3.080
+        \end{verbatim}
+
+        Also, PARI is also faster than NTL if one uses the flag 1 to
+        the mathnf routine.  The above takes 16 seconds in PARI.
+        """
+        cdef ntl_ZZ _D
+        if D == None:
+            _D = self.determinant()
+        else:
+            _D = ntl_ZZ(D)
+        _sig_on
+        return make_mat_ZZ(mat_ZZ_HNF(self.x, <ZZ_c*>_D.x))
+
+    def charpoly(self):
+        return make_ZZX(mat_ZZ_charpoly(self.x));
+
+    def LLL(self, a=3, b=4, return_U=False, verbose=False):
+        r"""
+        Performs LLL reduction of self (puts self in an LLL form).
+
+        self is an m x n matrix, viewed as m rows of n-vectors.  m may
+        be less than, equal to, or greater than n, and the rows need
+        not be linearly independent. self is transformed into an
+        LLL-reduced basis, and the return value is the rank r of self
+        so as det2 (see below).  The first m-r rows of self are zero.
+
+        More specifically, elementary row transformations are
+        performed on self so that the non-zero rows of new-self form
+        an LLL-reduced basis for the lattice spanned by the rows of
+        old-self.  The default reduction parameter is $\delta=3/4$,
+        which means that the squared length of the first non-zero
+        basis vector is no more than $2^{r-1}$ times that of the
+        shortest vector in the lattice.
+
+        det2 is calculated as the \emph{square} of the determinant of
+        the lattice---note that sqrt(det2) is in general an integer
+        only when r = n.
+
+        If return_U is True, a value U is returned which is the
+        transformation matrix, so that U is a unimodular m x m matrix
+        with U * old-self = new-self.  Note that the first m-r rows of
+        U form a basis (as a lattice) for the kernel of old-B.
+        
+        The parameters a and b allow an arbitrary reduction parameter
+        $\delta=a/b$, where $1/4 < a/b \leq 1$, where a and b are positive
+        integers.  For a basis reduced with parameter delta, the
+        squared length of the first non-zero basis vector is no more
+        than $1/(delta-1/4)^{r-1}$ times that of the shortest vector in
+        the lattice.
+                                    
+        The algorithm employed here is essentially the one in Cohen's
+        book: [H. Cohen, A Course in Computational Algebraic Number
+        Theory, Springer, 1993]
+        
+        INPUT:
+           a        -- parameter a as described above (default: 3)
+           b        -- parameter b as described above (default: 4)
+           return_U -- return U as described above
+           verbose  -- if True NTL will produce some verbatim messages on
+                       what's going on internally (default: False)
+
+        OUTPUT:
+            (rank,det2,[U]) where rank,det2, and U are as described
+            above and U is an optional return value if return_U is
+            True.
+
+        EXAMPLE:
+            sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9])
+            sage: M.LLL()
+            (2, 54)
+            sage: M
+            [[0 0 0]
+            [2 1 0]
+            [-1 1 3]
+            ]
+            sage: M=ntl.mat_ZZ(4,4,[-6,9,-15,-18,4,-6,10,12,10,-16,18,35,-24,36,-46,-82]); M
+            [[-6 9 -15 -18]
+            [4 -6 10 12]
+            [10 -16 18 35]
+            [-24 36 -46 -82]
+            ]
+            sage: M.LLL()
+            (3, 19140)
+            sage: M
+            [[0 0 0 0]
+            [0 -2 0 0]
+            [-2 1 -5 -6]
+            [0 -1 -7 5]
+            ]
+
+        WARNING: This method modifies self. So after applying this method your matrix
+        will be a vector of vectors.
+        """
+        cdef ZZ_c *det2
+        cdef mat_ZZ_c *U
+        if return_U:
+            _sig_on
+            U = new_mat_ZZ(self.nrows(),self.ncols())
+            rank = int(mat_ZZ_LLL_U(&det2, self.x, U, int(a), int(b), int(verbose)))
+            _sig_off
+            return rank, make_ZZ(det2), make_mat_ZZ(U)
+        else:
+            _sig_on
+            rank = int(mat_ZZ_LLL(&det2,self.x,int(a),int(b),int(verbose)))
+            _sig_off
+            return rank,make_ZZ(det2)
+            
+cdef make_mat_ZZ(mat_ZZ_c* x):
+    cdef ntl_mat_ZZ y
+    _sig_off
+    y = ntl_mat_ZZ(_INIT)
+    y.x = x
+    y.__nrows = mat_ZZ_nrows(y.x);
+    y.__ncols = mat_ZZ_ncols(y.x);
+    return y
+
+
+##############################################################################
+#
+# ntl_GF2X: Polynomials over GF(2) via NTL
+#
+# AUTHORS:
+#  - Martin Albrecht <malb@informatik.uni-bremen.de>
+#    2006-01: initial version (based on code by William Stein)
+#
+##############################################################################
+
+__have_GF2X_hex_repr = False # hex representation of GF2X_c
+
+
+cdef class ntl_GF2X:
+    """
+    Polynomials over GF(2) via NTL
+    """
+    # See ntl.pxd for definition of data members
+
+    def __reduce__(self):
+        raise NotImplementedError
+
+    def __dealloc__(self):
+        del_GF2X(self.gf2x_x)
+
+    def __repr__(self):
+        _sig_on
+        return string_delete(GF2X_to_str(self.gf2x_x))
+
+
+    def __mul__(ntl_GF2X self, other):
+        cdef ntl_GF2X y
+        if not isinstance(other, ntl_GF2X):
+            other = ntl_GF2X(other)
+        y = other
+        _sig_on
+        return make_GF2X(GF2X_mul(self.gf2x_x, y.gf2x_x))
+            
+    def __sub__(ntl_GF2X self, other):
+        cdef ntl_GF2X y
+        if not isinstance(other, ntl_GF2X):
+            other = ntl_GF2X(other)
+        y = other
+        _sig_on
+        return make_GF2X(GF2X_sub(self.gf2x_x, y.gf2x_x))
+
+    def __add__(ntl_GF2X self, other):
+        cdef ntl_GF2X y
+        if not isinstance(other, ntl_GF2X):
+            other = ntl_GF2X(other)
+        y = other
+        _sig_on
+        return make_GF2X(GF2X_add(self.gf2x_x, y.gf2x_x))
+            
+    def __neg__(ntl_GF2X self):
+        _sig_on
+        return make_GF2X(GF2X_neg(self.gf2x_x))
+
+    def __pow__(ntl_GF2X self, long e, ignored):
+        _sig_on
+        return make_GF2X(GF2X_pow(self.gf2x_x, e))
+
+
+    def __cmp__(ntl_GF2X self, ntl_GF2X other):
+        cdef int t
+        _sig_on
+        t = GF2X_eq(self.gf2x_x, other.gf2x_x)
+        _sig_off
+        if t:
+            return 0
+        return 1
+
+    def degree(ntl_GF2X self):
+        """
+        Returns the degree of this polynomial
+        """
+        return GF2X_deg(self.gf2x_x)
+
+    def list(ntl_GF2X self):
+        """
+        Represents this element as a list of binary digits.
+
+        EXAMPLES:
+             sage: e=ntl.GF2X([0,1,1])
+             sage: e.list()
+             [0, 1, 1]
+             sage: e=ntl.GF2X('0xff')
+             sage: e.list()
+             [1, 1, 1, 1, 1, 1, 1, 1]
+             
+        OUTPUT:
+             a list of digits representing the coefficients in this element's
+             polynomial representation
+        """
+        #yields e.g. "[1 1 0 0 1 1 0 1]"
+        _sig_on
+        s = string(GF2X_to_bin(self.gf2x_x))
+
+        #yields e.g. [1,1,0,0,1,1,0,1]
+        return map(int,list(s[1:][:len(s)-2].replace(" ","")))
+
+    
+    def bin(ntl_GF2X self):
+        """
+        Returns binary representation of this element. It is
+        the same as setting \code{ntl.hex_output(False)} and
+        representing this element afterwards. However it should be
+        faster and preserves the HexOutput state as opposed to
+        the above code.
+
+        EXAMPLES:
+             sage: e=ntl.GF2X([1,1,0,1,1,1,0,0,1])
+             sage: e.bin()
+             '[1 1 0 1 1 1 0 0 1]'
+
+        OUTPUT:
+            string representing this element in binary digits
+        
+        """
+        _sig_on
+        return string(GF2X_to_bin(self.gf2x_x))
+
+    def hex(ntl_GF2X self):
+        """
+        Returns hexadecimal representation of this element. It is
+        the same as setting \code{ntl.hex_output(True)} and
+        representing this element afterwards. However it should be
+        faster and preserves the HexOutput state as opposed to
+        the above code.
+
+        EXAMPLES:
+             sage: e=ntl.GF2X([1,1,0,1,1,1,0,0,1])
+             sage: e.hex()
+             '0xb31'
+
+        OUTPUT:
+            string representing this element in hexadecimal
+
+        """
+        _sig_on
+        return string(GF2X_to_hex(self.gf2x_x))
+
+    def _sage_(ntl_GF2X self,R=None,cache=None):
+        """
+        Returns a SAGE polynomial over GF(2) equivalent to
+        this element. If a ring R is provided it is used
+        to construct the polynomial in, otherwise
+        an appropriate ring is generated.
+
+        INPUT:
+            self  -- GF2X_c element
+            R     -- PolynomialRing over GF(2)
+            cache -- optional NTL to SAGE cache (dict)
+
+        OUTPUT:
+            polynomial in R
+        """
+        if R==None:
+            from sage.rings.polynomial.polynomial_ring import PolynomialRing
+            from sage.rings.finite_field import FiniteField
+            R = PolynomialRing(FiniteField(2), 'x')
+
+        if cache != None:
+            try:
+                return cache[self.hex()]
+            except KeyError:
+                cache[self.hex()] = R(self.list())
+                return cache[self.hex()]
+        
+        return R(self.list())
+
+    cdef set(self, void *y):  # only used internally for initialization; assumes self.gf2x_x not set yet!
+        self.gf2x_x = <GF2X_c*> y
+        
+cdef public make_GF2X(GF2X_c* x):
+    cdef ntl_GF2X y
+    _sig_off
+    y = ntl_GF2X()
+    y.gf2x_x = x
+    return y
+
+def make_new_GF2X(x=[]):
+    """
+    Constructs a new polynomial over GF(2).
+
+    A value may be passed to this constructor. If you pass a string
+    to the constructor please note that byte sequences and the hexadecimal
+    notation are little endian.  So e.g. '[0 1]' == '0x2' == x.
+
+    Input types are ntl.ZZ_px, strings, lists of digits, FiniteFieldElements
+    from extension fields over GF(2), Polynomials over GF(2), Integers, and finite
+    extension fields over GF(2) (uses modulus).
+
+    INPUT:
+        x -- value to be assigned to this element. See examples.
+
+    OUTPUT:
+        a new ntl.GF2X element
+
+    EXAMPLES:
+        sage: ntl.GF2X(ntl.ZZ_pX([1,1,3]))
+        [1 1 1]
+        sage: ntl.GF2X('0x1c')
+        [1 0 0 0 0 0 1 1]
+        sage: ntl.GF2X('[1 0 1 0]')
+        [1 0 1]
+        sage: ntl.GF2X([1,0,1,0])
+        [1 0 1]
+        sage: ntl.GF2X(GF(2**8,'a').gen()**20)
+        [0 0 1 0 1 1 0 1]
+        sage: ntl.GF2X(GF(2**8,'a'))
+        [1 0 1 1 1 0 0 0 1]
+        sage: ntl.GF2X(2)
+        [0 1]
+    """
+    from sage.rings.finite_field_element import FiniteField_ext_pariElement
+    from sage.rings.finite_field import FiniteField_ext_pari
+    from sage.rings.finite_field_givaro import FiniteField_givaro,FiniteField_givaroElement
+    from sage.rings.polynomial.polynomial_element_generic import Polynomial_dense_mod_p
+    from sage.rings.integer import Integer
+
+    if isinstance(x, Integer):
+        #binary repr, reversed, and "["..."]" added
+        x="["+x.binary()[::-1].replace(""," ")+"]"
+    elif type(x) == int:
+        #hex repr, "0x" stripped, reversed (!)
+        x="0x"+hex(x)[2:][::-1]
+    elif isinstance(x, Polynomial_dense_mod_p):
+        if x.base_ring().characteristic():
+            x=x._Polynomial_dense_mod_n__poly
+    elif isinstance(x, (FiniteField_ext_pari,FiniteField_givaro)):
+        if x.characteristic() == 2:
+            x= list(x.modulus())
+    elif isinstance(x, FiniteField_ext_pariElement):
+        if x.parent().characteristic() == 2:
+            x=x._pari_().centerlift().centerlift().subst('a',2).int_unsafe()
+            x="0x"+hex(x)[2:][::-1]
+    elif isinstance(x, FiniteField_givaroElement):
+        x = "0x"+hex(int(x))[2:][::-1]
+    s = str(x).replace(","," ")
+    cdef ntl_GF2X n
+    n = ntl_GF2X()
+    _sig_on
+    n.gf2x_x = str_to_GF2X(s)
+    _sig_off
+    return n
+
+
+
+##############################################################################
+#
+# ntl_GF2E: GF(2**x) via NTL
+#
+# AUTHORS:
+#  - Martin Albrecht <malb@informatik.uni-bremen.de>
+#    2006-01: initial version (based on cody by William Stein)
+#
+##############################################################################
+
+def GF2X_hex_repr(have_hex=None):
+    """
+    Represent GF2X_c and GF2E_c elements in the more compact
+    hexadecimal form to the user.
+
+    If no parameter is provided the currently set value will be
+    returned.
+
+    INPUT:
+        have_hex if True hex representation will be used
+    """
+    global __have_GF2X_hex_repr
+
+    if have_hex==None:
+        return __have_GF2X_hex_repr
+    
+    if have_hex==True:
+        GF2X_hex(1)
+    else:
+        GF2X_hex(0)
+    __have_GF2X_hex_repr=have_hex
+
+def ntl_GF2E_modulus(p=None):
+    """
+    Initializes the current modulus to P; required: deg(P) >= 1
+
+    The input is either ntl.GF2X or is tried to be converted to a
+    ntl.GF2X element.
+
+    If no parameter p is given: Yields copy of the current GF2E_c
+    modulus.
+
+    INPUT:
+        p -- modulus
+
+    EXAMPLES:
+        sage: ntl.GF2E_modulus([1,1,0,1,1,0,0,0,1])
+        sage: ntl.GF2E_modulus().hex()
+        '0xb11'
+    """
+    global __have_GF2E_modulus
+    cdef ntl_GF2X elem
+    
+    if p==None:
+        if __have_GF2E_modulus == True:
+            return make_GF2X(GF2E_modulus())
+        else:
+            raise "NoModulus"
+
+    if not isinstance(p,ntl_GF2X):
+        elem = make_new_GF2X(p)
+    else:
+        elem = p
+    
+    if(elem.degree()<1):
+        raise "DegreeToSmall"
+    
+    ntl_GF2E_set_modulus(<GF2X_c*>elem.gf2x_x)
+    __have_GF2E_modulus=True
+
+def ntl_GF2E_modulus_degree():
+    """
+    Returns deg(modulus) for GF2E_c elements
+    """
+    if __have_GF2E_modulus:
+        return GF2E_degree()
+    else:
+        raise "NoModulus"
+
+def ntl_GF2E_sage(names='a'):
+    """
+    Returns a SAGE FiniteField element matching the current modulus.
+
+    EXAMPLES:
+        sage: ntl.GF2E_modulus([1,1,0,1,1,0,0,0,1])
+        sage: ntl.GF2E_sage()
+        Finite Field in a of size 2^8
+    """
+    from sage.rings.finite_field import FiniteField
+    f = ntl_GF2E_modulus()._sage_()
+    return FiniteField(int(2)**GF2E_degree(),modulus=f,name=names)
+    
+
+def ntl_GF2E_random():
+    """
+    Returns a random element from GF2E_c modulo the current modulus.
+    """
+    _sig_on
+    return make_GF2E(GF2E_random());
+
+
+# make sure not to segfault
+__have_GF2E_modulus = False
+
+
+cdef class ntl_GF2E(ntl_GF2X):
+    r"""
+    The \\class{GF2E_c} represents a finite extension field over GF(2) using NTL.
+    Elements are represented as polynomials over GF(2) modulo \\code{ntl.GF2E_modulus()}.
+
+    This modulus must be set using \\code{ ntl.GF2E_modulus(p) } and is unique for
+    alle elements in ntl.GF2E. So it is not possible at the moment e.g. to have elements
+    in GF(2**4) and GF(2**8) at the same time. You might however be lucky and get away
+    with not touch the elements in GF(2**4) while having the GF(2**8) modulus set and vice
+    versa.
+    """
+
+    # See ntl.pxd for definition of data members
+    def __reduce__(self):
+        raise NotImplementedError
+
+    def __dealloc__(self):
+        del_GF2E(self.gf2e_x)
+
+    def __repr__(self):
+        _sig_on
+        return string_delete(GF2E_to_str(self.gf2e_x))
+
+
+    def __mul__(ntl_GF2E self, other):
+        cdef ntl_GF2E y
+        if not isinstance(other, ntl_GF2E):
+            other = ntl_GF2E(other)
+        y = other
+        _sig_on
+        return make_GF2E(GF2E_mul(self.gf2e_x, y.gf2e_x))
+            
+    def __sub__(ntl_GF2E self, other):
+        cdef ntl_GF2E y
+        if not isinstance(other, ntl_GF2E):
+            other = ntl_GF2E(other)
+        y = other
+        _sig_on
+        return make_GF2E(GF2E_sub(self.gf2e_x, y.gf2e_x))
+
+    def __add__(ntl_GF2E self, other):
+        cdef ntl_GF2E y
+        if not isinstance(other, ntl_GF2E):
+            other = ntl_GF2E(other)
+        y = other
+        _sig_on
+        return make_GF2E(GF2E_add(self.gf2e_x, y.gf2e_x))
+            
+    def __neg__(ntl_GF2E self):
+        _sig_on
+        return make_GF2E(GF2E_neg(self.gf2e_x))
+
+    def __pow__(ntl_GF2E self, long e, ignored):
+        _sig_on
+        return make_GF2E(GF2E_pow(self.gf2e_x, e))
+
+    def __cmp__(ntl_GF2E self, ntl_GF2E other):
+        cdef int t
+        _sig_on
+        t = GF2E_eq(self.gf2e_x, other.gf2e_x)
+        _sig_off
+        if t:
+            return 0
+        return 1
+
+    def is_zero(ntl_GF2E self):
+        """
+        Returns True if this element equals zero, False otherwise.
+        """
+        return bool(GF2E_is_zero(self.gf2e_x))
+
+    def is_one(ntl_GF2E self):
+        """
+        Returns True if this element equals one, False otherwise.
+        """
+        return bool(GF2E_is_one(self.gf2e_x))
+
+    def __copy__(self):
+        return make_GF2E(GF2E_copy(self.gf2e_x))
+
+    def copy(ntl_GF2E self):
+        """
+        Returns a copy of this element.
+        """
+        return make_GF2E(GF2E_copy(self.gf2e_x))
+
+    def trace(ntl_GF2E self):
+        """
+        Returns the trace of this element.
+        """
+        return GF2E_trace(self.gf2e_x)
+
+    def ntl_GF2X(ntl_GF2E self):
+        """
+        Returns a ntl.GF2X copy of this element.
+        """
+        return make_GF2X(self.gf2x_x)
+
+
+    def _sage_(ntl_GF2E self, k=None, cache=None):
+        """
+        Returns a \class{FiniteFieldElement} representation
+        of this element. If a \class{FiniteField} k is provided
+        it is constructed in this field if possible. A \class{FiniteField}
+        will be constructed if none is provided.
+
+        INPUT:
+            self  -- \class{GF2E_c} element
+            k     -- optional GF(2**deg)
+            cache -- optional NTL to SAGE conversion dictionary
+
+        OUTPUT:
+            FiniteFieldElement over k
+
+
+        EXAMPLE:
+            sage: ntl.GF2E_modulus([1,1,0,1,1,0,0,0,1])
+            sage: e = ntl.GF2E([0,1])
+            sage: a = e._sage_(); a
+            a
+
+        """
+        cdef int i
+        cdef int length
+        deg= GF2E_degree()
+        
+        if k==None:
+            from sage.rings.finite_field import FiniteField
+            f = ntl_GF2E_modulus()._sage_()
+            k = FiniteField(2**deg,name='a',modulus=f)
+
+        if cache != None:
+            try:
+                return cache[self.hex()]
+            except KeyError:
+                pass
+            
+
+        
+        a=k.gen()
+        l = self.list()
+
+        length = len(l)
+        ret = 0
+        
+        for i from 0 <= i < length:
+            if l[i]==1:
+                ret = ret + a**i
+
+        if cache != None:
+            cache[self.hex()] = ret
+            
+        return ret
+
+
+    cdef set(self, void *y):  # only used internally for initialization; assumes self.gf2e_x not set yet!
+        self.gf2e_x = <GF2E_c*> y
+        
+cdef public make_GF2E(GF2E_c* x):
+    cdef ntl_GF2E y
+    _sig_off
+    y = ntl_GF2E()
+    y.gf2e_x = x
+    y.gf2x_x = GF2E_ntl_GF2X(y.gf2e_x)
+    return y
+
+def make_new_GF2E(x=[]):
+    """
+    Constructs a new  finite field element in GF(2**x).
+
+    A modulus \emph{must} have been set with \code{ntl.GF2E_modulus(ntl.GF2X(<value>))}
+    when calling this constructor.  A value may be passed to this constructor. If you pass a string
+    to the constructor please note that byte sequences and the hexadecimal notation are Little Endian in NTL.
+    So e.g. '[0 1]' == '0x2' == x.
+
+    INPUT:
+        x -- value to be assigned to this element. Same types as ntl.GF2X() are accepted.
+
+    OUTPUT:
+        a new ntl.GF2E element
+
+    EXAMPLES:
+        sage: m=ntl.GF2E_modulus(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
+        sage: ntl.GF2E(ntl.ZZ_pX([1,1,3]))
+        [1 1 1]
+        sage: ntl.GF2E('0x1c')
+        [1 0 0 0 0 0 1 1]
+        sage: ntl.GF2E('[1 0 1 0]')
+        [1 0 1]
+        sage: ntl.GF2E([1,0,1,0])
+        [1 0 1]
+        sage: ntl.GF2E(GF(2**8,'a').gen()**20)
+        [0 0 1 0 1 1 0 1]
+    """
+    if not __have_GF2E_modulus:
+        raise "NoModulus"
+
+    s = str(make_new_GF2X(x))
+    cdef ntl_GF2E n
+    n = ntl_GF2E()
+    _sig_on
+    n.gf2e_x = str_to_GF2E(s)
+    n.gf2x_x = GF2E_ntl_GF2X(n.gf2e_x)
+    _sig_off
+    return n
+
+
+##############################################################################
+#
+# ntl_GF2EX: Polynomials over GF(2) via NTL
+#
+# AUTHORS:
+#  - Martin Albrecht <malb@informatik.uni-bremen.de> 2006-01: initial version
+#
+##############################################################################
+
+
+cdef class ntl_GF2EX:
+    r"""
+    """
+    # See ntl.pxd for definition of data members
+
+    def __reduce__(self):
+        raise NotImplementedError
+
+    def __dealloc__(self):
+        del_GF2EX(self.x)
+
+    def __repr__(self):
+        _sig_on
+        return string_delete(GF2EX_to_str(self.x))
+
+
+    def __mul__(ntl_GF2EX self, other):
+        cdef ntl_GF2EX y
+        if not isinstance(other, ntl_GF2EX):
+            other = ntl_GF2EX(other)
+        y = other
+        _sig_on
+        return make_GF2EX(GF2EX_mul(self.x, y.x))
+            
+    def __sub__(ntl_GF2EX self, other):
+        cdef ntl_GF2EX y
+        if not isinstance(other, ntl_GF2EX):
+            other = ntl_GF2EX(other)
+        y = other
+        _sig_on
+        return make_GF2EX(GF2EX_sub(self.x, y.x))
+
+    def __add__(ntl_GF2EX self, other):
+        cdef ntl_GF2EX y
+        if not isinstance(other, ntl_GF2EX):
+            other = ntl_GF2EX(other)
+        y = other
+        _sig_on
+        return make_GF2EX(GF2EX_add(self.x, y.x))
+            
+    def __neg__(ntl_GF2EX self):
+        _sig_on
+        return make_GF2EX(GF2EX_neg(self.x))
+
+    def __pow__(ntl_GF2EX self, long e, ignored):
+        _sig_on
+        return make_GF2EX(GF2EX_pow(self.x, e))
+
+    cdef set(self, void *y):  # only used internally for initialization; assumes self.x not set yet!
+        self.x = <GF2EX_c*> y
+        
+cdef public make_GF2EX(GF2EX_c* x):
+    cdef ntl_GF2EX y
+    _sig_off
+    y = ntl_GF2EX()
+    y.x = x
+    return y
+
+def make_new_GF2EX(x='[]'):
+    s = str(x)
+    cdef ntl_GF2EX n
+    n = ntl_GF2EX()
+    _sig_on
+    n.x = str_to_GF2EX(s)
+    _sig_off
+    return n
+
+
+##############################################################################
+#
+# ntl_mat_GF2E: Matrices over the GF(2**x) via NTL
+#
+# AUTHORS:
+#  - Martin Albrecht <malb@informatik.uni-bremen.de>
+#    2006-01: initial version (based on cody by William Stein)
+#
+##############################################################################
+
+
+cdef class ntl_mat_GF2E:
+    r"""
+    The \class{mat_GF2E_c} class implements arithmetic with matrices over $GF(2**x)$.
+    """
+    def __init__(self, nrows=0, ncols=0, v=None):
+        """
+        Constructs a matrix over ntl.GF2E.
+
+        INPUT:
+            nrows -- number of rows
+            ncols -- nomber of columns
+            v     -- either list or Matrix over GF(2**x)
+
+        EXAMPLES:
+            sage: ntl.GF2E_modulus([1,1,0,1,1,0,0,0,1])
+            sage: m=ntl.mat_GF2E(10,10)
+            sage: m=ntl.mat_GF2E(Matrix(GF(2**8, 'a'),10,10))
+            sage: m=ntl.mat_GF2E(10,10,[ntl.GF2E_random() for x in xrange(10*10)])
+        """
+
+        if nrows is _INIT:
+            return
+
+        cdef unsigned long _nrows, _ncols
+
+        import sage.matrix.matrix
+        if sage.matrix.matrix.is_Matrix(nrows):
+            _nrows = nrows.nrows()
+            _ncols = nrows.ncols()
+            v     = nrows.list()
+        else:
+            _nrows = nrows
+            _ncols = ncols
+            
+        if not __have_GF2E_modulus:
+            raise "NoModulus"
+        cdef unsigned long i, j
+        cdef ntl_GF2E tmp
+
+        
+        self.x = new_mat_GF2E(_nrows, _ncols)
+        self.__nrows = _nrows
+        self.__ncols = _ncols
+        if v != None:
+            _sig_on
+            for i from 0 <= i < _nrows:
+                for j from 0 <= j < _ncols:
+                    elem = v[i*_ncols+j]
+                    if not isinstance(elem, ntl_GF2E):
+                        tmp=make_new_GF2E(elem)
+                    else:
+                        tmp=elem
+                    mat_GF2E_setitem(self.x, i, j, <GF2E_c*> tmp.gf2e_x)
+            _sig_off
+            
+    def __reduce__(self):
+        raise NotImplementedError
+
+
+    def __dealloc__(self):
+        del_mat_GF2E(self.x)
+
+    def __repr__(self):
+        _sig_on
+        return string_delete(mat_GF2E_to_str(self.x))
+
+    def __mul__(ntl_mat_GF2E self, other):
+        cdef ntl_mat_GF2E y
+        if not isinstance(other, ntl_mat_GF2E):
+            other = ntl_mat_GF2E(other)
+        y = other
+        _sig_on
+        return make_mat_GF2E(mat_GF2E_mul(self.x, y.x))
+            
+    def __sub__(ntl_mat_GF2E self, other):
+        cdef ntl_mat_GF2E y
+        if not isinstance(other, ntl_mat_GF2E):
+            other = ntl_mat_GF2E(other)
+        y = other
+        _sig_on
+        return make_mat_GF2E(mat_GF2E_sub(self.x, y.x))
+
+    def __add__(ntl_mat_GF2E self, other):
+        cdef ntl_mat_GF2E y
+        if not isinstance(other, ntl_mat_GF2E):
+            other = ntl_mat_GF2E(other)
+        y = other
+        _sig_on
+        return make_mat_GF2E(mat_GF2E_add(self.x, y.x))
+            
+    def __pow__(ntl_mat_GF2E self, long e, ignored):
+        _sig_on
+        return make_mat_GF2E(mat_GF2E_pow(self.x, e))
+
+    def nrows(self):
+        """
+        Number of rows
+        """
+        return self.__nrows
+    
+    def ncols(self):
+        """
+        Number of columns
+        """
+        return self.__ncols
+
+    def __setitem__(self, ij, x):
+        cdef ntl_GF2E y
+        cdef int i, j
+        if not isinstance(x, ntl_GF2E):
+            x = make_new_GF2E(x)
+        y = x
+
+        from sage.rings.integer import Integer
+        if isinstance(ij, tuple) and len(ij) == 2:
+            i, j = ij
+        elif self.ncols()==1 and (isinstance(ij, Integer) or type(ij)==int):
+            i, j = ij,0
+        elif self.nrows()==1 and (isinstance(ij, Integer) or type(ij)==int):
+            i, j = 0,ij
+        else:
+            raise TypeError, 'ij is not a matrix index'
+
+        if i < 0 or i >= self.__nrows or j < 0 or j >= self.__ncols:
+            raise IndexError, "array index out of range"
+        mat_GF2E_setitem(self.x, i, j, <GF2E_c*> y.gf2e_x)
+
+    def __getitem__(self, ij):
+        cdef int i, j
+        from sage.rings.integer import Integer
+        if isinstance(ij, tuple) and len(ij) == 2:
+            i, j = ij
+        elif self.ncols()==1 and (isinstance(ij, Integer) or type(ij)==int):
+            i, j = ij,0
+        elif self.nrows()==1 and (isinstance(ij, Integer) or type(ij)==int):
+            i, j = 0,ij
+        else:
+            raise TypeError, 'ij is not a matrix index'
+        if i < 0 or i >= self.__nrows or j < 0 or j >= self.__ncols:
+            raise IndexError, "array index out of range"
+        return make_GF2E(mat_GF2E_getitem(self.x, i+1, j+1))
+
+    def determinant(self):
+        """
+        Returns the determinant.
+        """
+        _sig_on
+        return make_GF2E(mat_GF2E_determinant(self.x))
+
+    def echelon_form(self,ncols=0):
+        """
+        Performs unitary row operations so as to bring this matrix into row echelon
+        form.  If the optional argument \code{ncols} is supplied, stops when first ncols
+        columns are in echelon form.  The return value is the rank (or the
+        rank of the first ncols columns).
+
+        INPUT:
+           ncols -- number of columns to process
+
+        TODO: what is the output; does it return the rank?
+        """
+        cdef long w
+        w = ncols
+        _sig_on
+        return mat_GF2E_gauss(self.x, w)
+
+    def list(self):
+        """
+        Returns a list of the entries in this matrix
+
+        EXAMPLES:
+            sage: ntl.GF2E_modulus([1,1,0,1,1,0,0,0,1])
+            sage: m = ntl.mat_GF2E(2,2,[ntl.GF2E_random() for x in xrange(2*2)])
+            sage: m.list()                   # random output
+            [[1 0 1 0 1 0 1 1], [0 1 0 0 0 0 1], [0 0 0 1 0 0 1], [1 1 1 0 0 0 0 1]]
+        """
+        cdef unsigned long i, j
+        v = []
+        for i from 0 <= i < self.__nrows:
+            for j from 0 <= j < self.__ncols:
+                v.append(self[i,j])
+        return v
+
+    def is_zero(self):
+        cdef long isZero
+        _sig_on
+        isZero = mat_GF2E_is_zero(self.x)
+        _sig_off
+        if isZero==0:
+            return False
+        else:
+            return True
+
+    def _sage_(ntl_mat_GF2E self, k=None, cache=None):
+        """
+        Returns a \class{Matrix} over a FiniteField representation
+        of this element.
+
+        INPUT:
+            self  -- \class{mat_GF2E_c} element
+            k     -- optional GF(2**deg)
+            cache -- optional NTL to SAGE conversion dictionary
+
+        OUTPUT:
+            Matrix over k
+        """
+        if k==None:
+            k = ntl_GF2E_sage()
+        l = []
+        for elem in self.list():
+            l.append(elem._sage_(k, cache))
+
+        from sage.matrix.constructor import Matrix
+        return Matrix(k,self.nrows(),self.ncols(),l)
+
+    def transpose(ntl_mat_GF2E self):
+        """
+        Returns the transposed matrix of self.
+
+        OUTPUT:
+            transposed Matrix
+        """
+        _sig_on
+        return make_mat_GF2E(mat_GF2E_transpose(self.x))
+            
+cdef make_mat_GF2E(mat_GF2E_c* x):
+    cdef ntl_mat_GF2E y
+    _sig_off
+    y = ntl_mat_GF2E(_INIT)
+    y.x = x
+    y.__nrows = mat_GF2E_nrows(y.x);
+    y.__ncols = mat_GF2E_ncols(y.x);
+    return y
Index: age/libs/ntl/ntl_GF2E.pxd
===================================================================
--- sage/libs/ntl/ntl_GF2E.pxd	(revision 6418)
+++ 	(revision )
@@ -1,7 +1,0 @@
-include "decl.pxi"
-include "../../ext/cdefs.pxi"
-
-from ntl_GF2X cimport ntl_GF2X
-
-cdef class ntl_GF2E(ntl_GF2X):
-    cdef GF2E_c gf2e_x
Index: age/libs/ntl/ntl_GF2E.pyx
===================================================================
--- sage/libs/ntl/ntl_GF2E.pyx	(revision 6425)
+++ 	(revision )
@@ -1,378 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2005 William Stein <wstein@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/
-#*****************************************************************************
-
-include "../../ext/interrupt.pxi"
-include "../../ext/stdsage.pxi"
-include 'misc.pxi'
-include 'decl.pxi'
-
-from ntl_GF2X cimport ntl_GF2X
-
-cdef make_GF2X(GF2X_c *x):
-    """ These make_XXXX functions are deprecated and should be phased out."""
-    cdef ntl_GF2X y
-    _sig_off
-    y = ntl_GF2X()
-    y.gf2x_x = x[0]
-    GF2X_delete(x)
-    return y
-
-##############################################################################
-#
-# ntl_GF2E: GF(2**x) via NTL
-#
-# AUTHORS:
-#  - Martin Albrecht <malb@informatik.uni-bremen.de>
-#    2006-01: initial version (based on cody by William Stein)
-#
-##############################################################################
-
-def GF2X_hex_repr(have_hex=None):
-    """
-    Represent GF2X and GF2E elements in the more compact
-    hexadecimal form to the user.
-
-    If no parameter is provided the currently set value will be
-    returned.
-
-    INPUT:
-        have_hex if True hex representation will be used
-    """
-    global __have_GF2X_hex_repr
-
-    if have_hex==None:
-        return __have_GF2X_hex_repr
-    
-    if have_hex==True:
-        GF2X_hex(1)
-    else:
-        GF2X_hex(0)
-    __have_GF2X_hex_repr=have_hex
-
-def ntl_GF2E_modulus(p=None):
-    """
-    Initializes the current modulus to P; required: deg(P) >= 1
-
-    The input is either ntl.GF2X or is tried to be converted to a
-    ntl.GF2X element.
-
-    If no parameter p is given: Yields copy of the current GF2E
-    modulus.
-
-    INPUT:
-        p -- modulus
-
-    EXAMPLES:
-        sage: ntl.GF2E_modulus([1,1,0,1,1,0,0,0,1])
-        sage: ntl.GF2E_modulus().hex()
-        '0xb11'
-    """
-    global __have_GF2E_modulus
-    cdef ntl_GF2X elem
-    
-    if p==None:
-        if __have_GF2E_modulus:
-            return make_GF2X(<GF2X_c*>GF2E_modulus())
-        else:
-            raise "NoModulus"
-
-    if not isinstance(p,ntl_GF2X):
-        elem = ntl_GF2X(p)
-    else:
-        elem = p
-    
-    if(elem.degree()<1):
-        raise "DegreeToSmall"
-    
-    ntl_GF2E_set_modulus(<GF2X_c*>&elem.gf2x_x)
-    __have_GF2E_modulus = True
-
-def ntl_GF2E_modulus_degree():
-    """
-    Returns deg(modulus) for GF2E elements
-    """
-    if __have_GF2E_modulus:
-        return GF2E_degree()
-    else:
-        raise "NoModulus"
-
-def ntl_GF2E_sage(names='a'):
-    """
-    Returns a SAGE FiniteField element matching the current modulus.
-
-    EXAMPLES:
-        sage: ntl.GF2E_modulus([1,1,0,1,1,0,0,0,1])
-        sage: ntl.GF2E_sage()
-        Finite Field in a of size 2^8
-    """
-    from sage.rings.finite_field import FiniteField
-    f = ntl_GF2E_modulus()._sage_()
-    return FiniteField(int(2)**GF2E_degree(),modulus=f,name=names)
-
-
-def ntl_GF2E_random():
-    """
-    Returns a random element from GF2E modulo the current modulus.
-    """
-    cdef ntl_GF2E r = ntl_GF2E()
-    _sig_on
-    r.gf2e_x = GF2E_random()
-    _sig_off
-    return r
-
-def unpickle_GF2E(hex, mod):
-    ntl_GF2E_modulus(mod)
-    return ntl_GF2E(hex)
-
-
-# make sure not to segfault
-__have_GF2E_modulus = False
-
-
-cdef class ntl_GF2E(ntl_GF2X):
-    r"""
-    The \\class{GF2E} represents a finite extension field over GF(2) using NTL.
-    Elements are represented as polynomials over GF(2) modulo \\code{ntl.GF2E_modulus()}.
-
-    This modulus must be set using \\code{ ntl.GF2E_modulus(p) } and is unique for
-    alle elements in ntl.GF2E. So it is not possible at the moment e.g. to have elements
-    in GF(2**4) and GF(2**8) at the same time. You might however be lucky and get away
-    with not touch the elements in GF(2**4) while having the GF(2**8) modulus set and vice
-    versa.
-    """
-
-    def __init__(self,x=[]):
-        """
-        Constructs a new  finite field element in GF(2**x).
-        
-        A modulus \emph{must} have been set with \code{ntl.GF2E_modulus(ntl.GF2X(<value>))}
-        when calling this constructor.  A value may be passed to this constructor. If you pass a string
-        to the constructor please note that byte sequences and the hexadecimal notation are Little Endian in NTL.
-        So e.g. '[0 1]' == '0x2' == x.
-        
-        INPUT:
-            x -- value to be assigned to this element. Same types as ntl.GF2X() are accepted.
-        
-        OUTPUT:
-            a new ntl.GF2E element
-        
-        EXAMPLES:
-            sage: m=ntl.GF2E_modulus(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
-            sage: ntl.GF2E(ntl.ZZ_pX([1,1,3],2))
-            [1 1 1]
-            sage: ntl.GF2E('0x1c')
-            [1 0 0 0 0 0 1 1]
-            sage: ntl.GF2E('[1 0 1 0]')
-            [1 0 1]
-            sage: ntl.GF2E([1,0,1,0])
-            [1 0 1]
-            sage: ntl.GF2E(GF(2**8,'a').gen()**20)
-            [0 0 1 0 1 1 0 1]
-        """
-        if not __have_GF2E_modulus:
-            raise "NoModulus"
-
-        s = str(ntl_GF2X(x))
-        _sig_on
-        GF2E_from_str(&self.gf2e_x, s)
-        self.gf2x_x = GF2E_rep(self.gf2e_x)
-        _sig_off
-
-    def __new__(self, x=[]):
-        GF2E_construct(&self.gf2e_x)
-
-    def __dealloc__(self):
-        GF2E_destruct(&self.gf2e_x)
-
-    def __reduce__(self):
-        """
-        EXAMPES: 
-            sage: m=ntl.GF2E_modulus(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
-            sage: a = ntl.GF2E(ntl.ZZ_pX([1,1,3],2))
-            sage: m=ntl.GF2E_modulus(ntl.GF2X([1,1,0,1,1,0,1,0,1]))
-            sage: loads(dumps(a)) == a
-            True
-        """
-        return unpickle_GF2E, (self.ntl_GF2X().hex(), ntl_GF2E_modulus())
-
-    def __repr__(self):
-        _sig_on
-        return string_delete(GF2E_to_str(&self.gf2e_x))
-
-    def __mul__(ntl_GF2E self, other):
-        cdef ntl_GF2E y
-        cdef ntl_GF2E r = ntl_GF2E()
-        if not isinstance(other, ntl_GF2E):
-            other = ntl_GF2E(other)
-        y = other
-        _sig_on
-        GF2E_mul(r.gf2e_x, self.gf2e_x, y.gf2e_x)
-        _sig_off
-        return r
-
-    def __sub__(ntl_GF2E self, other):
-        cdef ntl_GF2E y
-        cdef ntl_GF2E r = ntl_GF2E()
-        if not isinstance(other, ntl_GF2E):
-            other = ntl_GF2E(other)
-        y = other
-        _sig_on
-        GF2E_sub(r.gf2e_x, self.gf2e_x, y.gf2e_x)
-        _sig_off
-        return r
-
-    def __add__(ntl_GF2E self, other):
-        cdef ntl_GF2E y
-        cdef ntl_GF2E r = ntl_GF2E()
-        if not isinstance(other, ntl_GF2E):
-            other = ntl_GF2E(other)
-        y = other
-        _sig_on
-        GF2E_add(r.gf2e_x, self.gf2e_x, y.gf2e_x)
-        _sig_off
-        return r
-
-    def __neg__(ntl_GF2E self):
-        cdef ntl_GF2E r = ntl_GF2E()
-        _sig_on
-        GF2E_negate(r.gf2e_x, self.gf2e_x)
-        _sig_off
-        return r
-
-    def __pow__(ntl_GF2E self, long e, ignored):
-        cdef ntl_GF2E y
-        cdef ntl_GF2E r
-        if not isinstance(other, ntl_GF2E):
-            other = ntl_GF2E(other)
-        y = other
-        r = ntl_GF2E()
-        _sig_on
-        GF2E_power(r.gf2e_x, self.gf2e_x, e)
-        _sig_off
-        return r
-
-    def __cmp__(ntl_GF2E self, ntl_GF2E other):
-        cdef int t
-        _sig_on
-        t = GF2E_eq(&self.gf2e_x, &other.gf2e_x)
-        _sig_off
-        if t:
-            return 0
-        return 1
-
-    def is_zero(ntl_GF2E self):
-        """
-        Returns True if this element equals zero, False otherwise.
-        """
-        return bool(GF2E_is_zero(&self.gf2e_x))
-
-    def is_one(ntl_GF2E self):
-        """
-        Returns True if this element equals one, False otherwise.
-        """
-        return bool(GF2E_is_one(&self.gf2e_x))
-
-    def __copy__(self):
-        cdef ntl_GF2E r = ntl_GF2E()
-        _sig_on
-        r.gf2e_x = self.gf2e_x
-        r.gf2x_x = self.gf2x_x
-        _sig_off
-        return r
-
-    def copy(ntl_GF2E self):
-        """
-        Returns a copy of this element.
-        """
-        cdef ntl_GF2E r = ntl_GF2E()
-        _sig_on
-        r.gf2e_x = self.gf2e_x
-        r.gf2x_x = self.gf2x_x
-        _sig_off
-        return r
-
-    def trace(ntl_GF2E self):
-        """
-        Returns the trace of this element.
-        """
-        return GF2E_trace(&self.gf2e_x)
-
-    def ntl_GF2X(ntl_GF2E self):
-        """
-        Returns a ntl.GF2X copy of this element.
-        
-        EXAMPLE: 
-            sage: m=ntl.GF2E_modulus(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
-            sage: a = ntl.GF2E('0x1c')
-            sage: a.ntl_GF2X()
-            [1 0 0 0 0 0 1 1]
-            sage: a.copy().ntl_GF2X()
-            [1 0 0 0 0 0 1 1]
-        """
-        cdef ntl_GF2X x = ntl_GF2X()
-        x.gf2x_x = self.gf2x_x
-        return x
-
-    def _sage_(ntl_GF2E self, k=None, cache=None):
-        """
-        Returns a \class{FiniteFieldElement} representation
-        of this element. If a \class{FiniteField} k is provided
-        it is constructed in this field if possible. A \class{FiniteField}
-        will be constructed if none is provided.
-
-        INPUT:
-            self  -- \class{GF2E} element
-            k     -- optional GF(2**deg)
-            cache -- optional NTL to SAGE conversion dictionary
-
-        OUTPUT:
-            FiniteFieldElement over k
-
-        EXAMPLE:
-            sage: ntl.GF2E_modulus([1,1,0,1,1,0,0,0,1])
-            sage: e = ntl.GF2E([0,1])
-            sage: a = e._sage_(); a
-            a
-
-        """
-        cdef int i
-        cdef int length
-        deg= GF2E_degree()
-
-        if k==None:
-            from sage.rings.finite_field import FiniteField
-            f = ntl_GF2E_modulus()._sage_()
-            k = FiniteField(2**deg,name='a',modulus=f)
-
-        if cache != None:
-            try:
-                return cache[self.hex()]
-            except KeyError:
-                pass
-
-        a=k.gen()
-        l = self.list()
-
-        length = len(l)
-        ret = 0
-
-        for i from 0 <= i < length:
-            if l[i]==1:
-                ret = ret + a**i
-
-        if cache != None:
-            cache[self.hex()] = ret
-
-        return ret
Index: age/libs/ntl/ntl_GF2EX.pxd
===================================================================
--- sage/libs/ntl/ntl_GF2EX.pxd	(revision 6418)
+++ 	(revision )
@@ -1,5 +1,0 @@
-include "decl.pxi"
-include "../../ext/cdefs.pxi"
-
-cdef class ntl_GF2EX:
-    cdef GF2EX_c x
Index: age/libs/ntl/ntl_GF2EX.pyx
===================================================================
--- sage/libs/ntl/ntl_GF2EX.pyx	(revision 6418)
+++ 	(revision )
@@ -1,104 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2005 William Stein <wstein@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/
-#*****************************************************************************
-
-include "../../ext/interrupt.pxi"
-include "../../ext/stdsage.pxi"
-include 'misc.pxi'
-include 'decl.pxi'
-
-##############################################################################
-#
-# ntl_GF2EX: Polynomials over GF(2) via NTL
-#
-# AUTHORS:
-#  - Martin Albrecht <malb@informatik.uni-bremen.de> 2006-01: initial version
-#
-##############################################################################
-
-cdef class ntl_GF2EX:
-    r"""
-    """
-    def __init__(self, x=[]):
-        """
-        EXAMPLES:
-            sage: ntl.set_modulus(ntl.ZZ(3))
-            sage: m=ntl.GF2E_modulus(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
-            sage: ntl.GF2EX('[[1 0] [2 1]]')
-            [[1] [0 1]]
-        """
-        s = str(x)
-        _sig_on
-        GF2EX_from_str(&self.x, s)
-        _sig_off
-
-    def __new__(self, x=[]):
-        GF2EX_construct(&self.x)
-
-    def __dealloc__(self):
-        GF2EX_destruct(&self.x)
-
-    def __reduce__(self):
-        raise NotImplementedError
-
-    def __repr__(self):
-        _sig_on
-        return string_delete(GF2EX_to_str(&self.x))
-
-    def __mul__(ntl_GF2EX self, other):
-        cdef ntl_GF2EX y
-        cdef ntl_GF2EX r = ntl_GF2EX()
-        if not isinstance(other, ntl_GF2EX):
-            other = ntl_GF2EX(other)
-        y = other
-        _sig_on
-        GF2EX_mul(r.x, self.x, y.x)
-        _sig_off
-        return r
-
-    def __sub__(ntl_GF2EX self, other):
-        cdef ntl_GF2EX y
-        cdef ntl_GF2EX r = ntl_GF2EX()
-        if not isinstance(other, ntl_GF2EX):
-            other = ntl_GF2EX(other)
-        y = other
-        _sig_on
-        GF2EX_sub(r.x, self.x, y.x)
-        _sig_off
-        return r
-
-    def __add__(ntl_GF2EX self, other):
-        cdef ntl_GF2EX y
-        cdef ntl_GF2EX r = ntl_GF2EX()
-        if not isinstance(other, ntl_GF2EX):
-            other = ntl_GF2EX(other)
-        y = other
-        _sig_on
-        GF2EX_add(r.x, self.x, y.x)
-        _sig_off
-        return r
-
-    def __neg__(ntl_GF2EX self):
-        cdef ntl_GF2EX r = ntl_GF2EX()
-        _sig_on
-        GF2EX_negate(r.x, self.x)
-        _sig_off
-        return r
-
-    def __pow__(ntl_GF2EX self, long e, ignored):
-        cdef ntl_GF2EX r = ntl_GF2EX()
-        _sig_on
-        GF2EX_power(r.x, self.x, e)
-        _sig_off
-        return r
Index: age/libs/ntl/ntl_GF2X.pxd
===================================================================
--- sage/libs/ntl/ntl_GF2X.pxd	(revision 6418)
+++ 	(revision )
@@ -1,5 +1,0 @@
-include "decl.pxi"
-include "../../ext/cdefs.pxi"
-
-cdef class ntl_GF2X:
-    cdef GF2X_c gf2x_x
Index: age/libs/ntl/ntl_GF2X.pyx
===================================================================
--- sage/libs/ntl/ntl_GF2X.pyx	(revision 6424)
+++ 	(revision )
@@ -1,284 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2005 William Stein <wstein@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/
-#*****************************************************************************
-
-include "../../ext/interrupt.pxi"
-include "../../ext/stdsage.pxi"
-include 'misc.pxi'
-include 'decl.pxi'
-
-from ntl_ZZ import unpickle_class_value
-
-##############################################################################
-#
-# ntl_GF2X: Polynomials over GF(2) via NTL
-#
-# AUTHORS:
-#  - Martin Albrecht <malb@informatik.uni-bremen.de>
-#    2006-01: initial version (based on code by William Stein)
-#
-##############################################################################
-
-cdef bint __have_GF2X_hex_repr = False # hex representation of GF2X
-
-
-cdef class ntl_GF2X:
-    """
-    Polynomials over GF(2) via NTL
-    """
-    def __init__(self, x=[]):
-        """
-        Constructs a new polynomial over GF(2).
-
-        A value may be passed to this constructor. If you pass a string
-        to the constructor please note that byte sequences and the hexadecimal
-        notation are little endian.  So e.g. '[0 1]' == '0x2' == x.
-
-        Input types are ntl.ZZ_px, strings, lists of digits, FiniteFieldElements
-        from extension fields over GF(2), Polynomials over GF(2), Integers, and finite
-        extension fields over GF(2) (uses modulus).
-
-        INPUT:
-            x -- value to be assigned to this element. See examples.
-
-        OUTPUT:
-            a new ntl.GF2X element
-
-        EXAMPLES:
-            sage: ntl.GF2X(ntl.ZZ_pX([1,1,3],2))
-            [1 1 1]
-            sage: ntl.GF2X('0x1c')
-            [1 0 0 0 0 0 1 1]
-            sage: ntl.GF2X('[1 0 1 0]')
-            [1 0 1]
-            sage: ntl.GF2X([1,0,1,0])
-            [1 0 1]
-            sage: ntl.GF2X(GF(2**8,'a').gen()**20)
-            [0 0 1 0 1 1 0 1]
-            sage: ntl.GF2X(GF(2**8,'a'))
-            [1 0 1 1 1 0 0 0 1]
-            sage: ntl.GF2X(2)
-            [0 1]
-        """
-        from sage.rings.finite_field_element import FiniteField_ext_pariElement
-        from sage.rings.finite_field import FiniteField_ext_pari
-        from sage.rings.finite_field_givaro import FiniteField_givaro,FiniteField_givaroElement
-        from sage.rings.polynomial.polynomial_element_generic import Polynomial_dense_mod_p
-        from sage.rings.integer import Integer
-
-        if isinstance(x, Integer):
-            #binary repr, reversed, and "["..."]" added
-            x="["+x.binary()[::-1].replace(""," ")+"]"
-        elif type(x) == int:
-            #hex repr, "0x" stripped, reversed (!)
-            x="0x"+hex(x)[2:][::-1]
-        elif isinstance(x, Polynomial_dense_mod_p):
-            if x.base_ring().characteristic():
-                x=x._Polynomial_dense_mod_n__poly
-        elif isinstance(x, (FiniteField_ext_pari,FiniteField_givaro)):
-            if x.characteristic() == 2:
-                x= list(x.modulus())
-        elif isinstance(x, FiniteField_ext_pariElement):
-            if x.parent().characteristic() == 2:
-                x=x._pari_().centerlift().centerlift().subst('a',2).int_unsafe()
-                x="0x"+hex(x)[2:][::-1]
-        elif isinstance(x, FiniteField_givaroElement):
-            x = "0x"+hex(int(x))[2:][::-1]
-        s = str(x).replace(","," ")
-        _sig_on
-        GF2X_from_str(&self.gf2x_x, s)
-        _sig_off
-
-    def __new__(self, x=[]):
-        GF2X_construct(&self.gf2x_x)
-
-    def __dealloc__(self):
-        GF2X_destruct(&self.gf2x_x)
-
-    def __reduce__(self):
-        """
-        EXAMPLES:
-            sage: f = ntl.GF2X(ntl.ZZ_pX([1,1,3],2))
-            sage: loads(dumps(f)) == f
-            True
-            sage: f = ntl.GF2X('0x1c')
-            sage: loads(dumps(f)) == f
-            True
-        """
-        return unpickle_class_value, (ntl_GF2X, self.hex())
-
-    def __repr__(self):
-        _sig_on
-        return string_delete(GF2X_to_str(&self.gf2x_x))
-
-    def __mul__(ntl_GF2X self, other):
-        cdef ntl_GF2X y
-        cdef ntl_GF2X r = ntl_GF2X()
-        if not isinstance(other, ntl_GF2X):
-            other = ntl_GF2X(other)
-        y = other
-        _sig_on
-        GF2X_mul(r.gf2x_x, self.gf2x_x, y.gf2x_x)
-        _sig_off
-        return r
-
-    def __sub__(ntl_GF2X self, other):
-        cdef ntl_GF2X y
-        cdef ntl_GF2X r = ntl_GF2X()
-        if not isinstance(other, ntl_GF2X):
-            other = ntl_GF2X(other)
-        y = other
-        _sig_on
-        GF2X_sub(r.gf2x_x, self.gf2x_x, y.gf2x_x)
-        _sig_off
-        return r
-
-    def __add__(ntl_GF2X self, other):
-        cdef ntl_GF2X y
-        cdef ntl_GF2X r = ntl_GF2X()
-        if not isinstance(other, ntl_GF2X):
-            other = ntl_GF2X(other)
-        y = other
-        _sig_on
-        GF2X_add(r.gf2x_x, self.gf2x_x, y.gf2x_x)
-        _sig_off
-        return r
-
-    def __neg__(ntl_GF2X self):
-        cdef ntl_GF2X r = ntl_GF2X()
-        _sig_on
-        GF2X_negate(r.gf2x_x, self.gf2x_x)
-        _sig_off
-        return r
-
-    def __pow__(ntl_GF2X self, long e, ignored):
-        cdef ntl_GF2X y
-        cdef ntl_GF2X r
-        if not isinstance(other, ntl_GF2X):
-            other = ntl_GF2X(other)
-        y = other
-        r = ntl_GF2X()
-        _sig_on
-        GF2X_power(r.gf2x_x, self.gf2x_x, e)
-        _sig_off
-        return r
-
-
-    def __cmp__(ntl_GF2X self, ntl_GF2X other):
-        cdef int t
-        _sig_on
-        t = GF2X_eq(&self.gf2x_x, &other.gf2x_x)
-        _sig_off
-        if t:
-            return 0
-        return 1
-
-    def degree(ntl_GF2X self):
-        """
-        Returns the degree of this polynomial
-        """
-        return GF2X_deg(&self.gf2x_x)
-
-    def list(ntl_GF2X self):
-        """
-        Represents this element as a list of binary digits.
-
-        EXAMPLES:
-             sage: e=ntl.GF2X([0,1,1])
-             sage: e.list()
-             [0, 1, 1]
-             sage: e=ntl.GF2X('0xff')
-             sage: e.list()
-             [1, 1, 1, 1, 1, 1, 1, 1]
-             
-        OUTPUT:
-             a list of digits representing the coefficients in this element's
-             polynomial representation
-        """
-        #yields e.g. "[1 1 0 0 1 1 0 1]"
-        _sig_on
-        s = string(GF2X_to_bin(&self.gf2x_x))
-
-        #yields e.g. [1,1,0,0,1,1,0,1]
-        return map(int,list(s[1:][:len(s)-2].replace(" ","")))
-
-    
-    def bin(ntl_GF2X self):
-        """
-        Returns binary representation of this element. It is
-        the same as setting \code{ntl.hex_output(False)} and
-        representing this element afterwards. However it should be
-        faster and preserves the HexOutput state as opposed to
-        the above code.
-
-        EXAMPLES:
-             sage: e=ntl.GF2X([1,1,0,1,1,1,0,0,1])
-             sage: e.bin()
-             '[1 1 0 1 1 1 0 0 1]'
-
-        OUTPUT:
-            string representing this element in binary digits
-        
-        """
-        _sig_on
-        return string(GF2X_to_bin(&self.gf2x_x))
-
-    def hex(ntl_GF2X self):
-        """
-        Returns hexadecimal representation of this element. It is
-        the same as setting \code{ntl.hex_output(True)} and
-        representing this element afterwards. However it should be
-        faster and preserves the HexOutput state as opposed to
-        the above code.
-
-        EXAMPLES:
-             sage: e=ntl.GF2X([1,1,0,1,1,1,0,0,1])
-             sage: e.hex()
-             '0xb31'
-
-        OUTPUT:
-            string representing this element in hexadecimal
-
-        """
-        _sig_on
-        return string(GF2X_to_hex(&self.gf2x_x))
-
-    def _sage_(ntl_GF2X self,R=None,cache=None):
-        """
-        Returns a SAGE polynomial over GF(2) equivalent to
-        this element. If a ring R is provided it is used
-        to construct the polynomial in, otherwise
-        an appropriate ring is generated.
-
-        INPUT:
-            self  -- GF2X element
-            R     -- PolynomialRing over GF(2)
-            cache -- optional NTL to SAGE cache (dict)
-
-        OUTPUT:
-            polynomial in R
-        """
-        if R==None:
-            from sage.rings.polynomial.polynomial_ring import PolynomialRing
-            from sage.rings.finite_field import FiniteField
-            R = PolynomialRing(FiniteField(2), 'x')
-
-        if cache != None:
-            try:
-                return cache[self.hex()]
-            except KeyError:
-                cache[self.hex()] = R(self.list())
-                return cache[self.hex()]
-
-        return R(self.list())
Index: age/libs/ntl/ntl_ZZ.pxd
===================================================================
--- sage/libs/ntl/ntl_ZZ.pxd	(revision 6418)
+++ 	(revision )
@@ -1,7 +1,0 @@
-
-include "decl.pxi"
-
-cdef class ntl_ZZ:
-    cdef ZZ_c x
-    cdef public int get_as_int(ntl_ZZ self)
-    cdef public void set_from_int(ntl_ZZ self, int value)
Index: age/libs/ntl/ntl_ZZ.pyx
===================================================================
--- sage/libs/ntl/ntl_ZZ.pyx	(revision 6425)
+++ 	(revision )
@@ -1,295 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2005 William Stein <wstein@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/
-#*****************************************************************************
-
-include "../../ext/interrupt.pxi"
-include "../../ext/stdsage.pxi"
-include "../../ext/cdefs.pxi"
-include 'misc.pxi'
-include 'decl.pxi'
-
-from sage.rings.integer import Integer
-from sage.rings.integer_ring import IntegerRing
-from sage.rings.integer cimport Integer
-from sage.rings.integer_ring cimport IntegerRing_class
-
-ZZ_sage = IntegerRing()
-
-cdef make_ZZ(ZZ_c* x):
-    cdef ntl_ZZ y
-    y = ntl_ZZ()
-    y.x = x[0]
-    ZZ_delete(x)
-    _sig_off
-    return y
-
-
-##############################################################################
-# ZZ: Arbitrary precision integers
-##############################################################################
-
-cdef class ntl_ZZ:
-    r"""
-    The \class{ZZ} class is used to represent signed, arbitrary length integers.
-
-    Routines are provided for all of the basic arithmetic operations, as
-    well as for some more advanced operations such as primality testing.
-    Space is automatically managed by the constructors and destructors.
-
-    This module also provides routines for generating small primes, and
-    fast routines for performing modular arithmetic on single-precision
-    numbers.
-    """
-    # See ntl.pxd for definition of data members
-    def __init__(self, v=None):
-        r"""
-        Initializes and NTL integer.
-
-        EXAMPLES:
-            sage: ntl.ZZ(12r)
-            12
-            sage: ntl.ZZ(Integer(95413094))
-            95413094
-            sage: ntl.ZZ(long(223895239852389582983))
-            223895239852389582983
-            sage: ntl.ZZ('-1')
-            -1
-
-        AUTHOR: Joel B. Mohler (2007-06-14)
-        """
-        if PY_TYPE_CHECK(v, ntl_ZZ):
-            self.x = (<ntl_ZZ>v).x
-        elif PyInt_Check(v):
-            ZZ_conv_int(self.x, v)
-        elif PyLong_Check(v):
-            ZZ_set_pylong(self.x, v)
-        elif PY_TYPE_CHECK(v, Integer):
-            self.set_from_sage_int(v)
-        elif v is not None:
-            v = str(v)
-            ZZ_from_str(&self.x, v)
-
-    def __new__(self, v=None):
-        ZZ_construct(&self.x)
-
-    def __dealloc__(self):
-        ZZ_destruct(&self.x)
-
-    def __repr__(self):
-        _sig_on
-        return string_delete(ZZ_to_str(&self.x))
-
-    def __reduce__(self):
-        """
-        sage: from sage.libs.ntl.ntl_ZZ import ntl_ZZ
-        sage: a = ntl_ZZ(-7)
-        sage: loads(dumps(a))
-        -7
-        """
-        return unpickle_class_value, (ntl_ZZ, self.get_as_sage_int())
-
-    def __mul__(self, other):
-        """
-            sage: n=ntl.ZZ(2983)*ntl.ZZ(2)
-            sage: n
-            5966
-        """
-        cdef ntl_ZZ r = PY_NEW(ntl_ZZ)
-        if not PY_TYPE_CHECK(self, ntl_ZZ):
-            self = ntl_ZZ(self)
-        if not PY_TYPE_CHECK(other, ntl_ZZ):
-            other = ntl_ZZ(other)
-        mul_ZZ(r.x, (<ntl_ZZ>self).x, (<ntl_ZZ>other).x)
-        return r
-
-    def __sub__(self, other):
-        """
-            sage: n=ntl.ZZ(2983)-ntl.ZZ(2)
-            sage: n
-            2981
-            sage: ntl.ZZ(2983)-2
-            2981
-        """
-        cdef ntl_ZZ r = PY_NEW(ntl_ZZ)
-        if not PY_TYPE_CHECK(self, ntl_ZZ):
-            self = ntl_ZZ(self)
-        if not PY_TYPE_CHECK(other, ntl_ZZ):
-            other = ntl_ZZ(other)
-        sub_ZZ(r.x, (<ntl_ZZ>self).x, (<ntl_ZZ>other).x)
-        return r
-
-    def __add__(self, other):
-        """
-            sage: n=ntl.ZZ(2983)+ntl.ZZ(2)
-            sage: n
-            2985
-            sage: ntl.ZZ(23)+2
-            25
-        """
-        cdef ntl_ZZ r = PY_NEW(ntl_ZZ)
-        if not PY_TYPE_CHECK(self, ntl_ZZ):
-            self = ntl_ZZ(self)
-        if not PY_TYPE_CHECK(other, ntl_ZZ):
-            other = ntl_ZZ(other)
-        add_ZZ(r.x, (<ntl_ZZ>self).x, (<ntl_ZZ>other).x)
-        return r
-
-    def __neg__(ntl_ZZ self):
-        cdef ntl_ZZ r = PY_NEW(ntl_ZZ)
-        ZZ_negate(r.x, self.x)
-        return r
-
-    def __pow__(ntl_ZZ self, long e, ignored):
-        """
-            sage: ntl.ZZ(23)^50
-            122008981252869411022491112993141891091036959856659100591281395343249
-        """
-        cdef ntl_ZZ r = ntl_ZZ()
-        power_ZZ(r.x, self.x, e)
-        return r
-
-    cdef int get_as_int(ntl_ZZ self):
-        r"""
-        Returns value as C int.
-        Return value is only valid if the result fits into an int.
-
-        AUTHOR: David Harvey (2006-08-05)
-        """
-        return ZZ_to_int(&self.x)
-
-    def get_as_int_doctest(self):
-        r"""
-        This method exists solely for automated testing of get_as_int().
-
-        sage: x = ntl.ZZ(42)
-        sage: i = x.get_as_int_doctest()
-        sage: print i
-         42
-        sage: print type(i)
-         <type 'int'>
-        """
-        return self.get_as_int()
-
-    def get_as_sage_int(self):
-        r"""
-        Gets the value as a sage int.
-
-        sage: n=ntl.ZZ(2983)
-        sage: type(n.get_as_sage_int())
-        <type 'sage.rings.integer.Integer'>
-
-        AUTHOR: Joel B. Mohler
-        """
-        return (<IntegerRing_class>ZZ_sage)._coerce_ZZ(&self.x)
-
-    cdef void set_from_int(ntl_ZZ self, int value):
-        r"""
-        Sets the value from a C int.
-
-        AUTHOR: David Harvey (2006-08-05)
-        """
-        ZZ_set_from_int(&self.x, value)
-
-    def set_from_sage_int(self, Integer value):
-        r"""
-        Sets the value from a sage int.
-
-        EXAMPLES:
-            sage: n=ntl.ZZ(2983)
-            sage: n
-            2983
-            sage: n.set_from_sage_int(1234)
-            sage: n
-            1234
-
-        AUTHOR: Joel B. Mohler
-        """
-        _sig_on
-        value._to_ZZ(&self.x)
-        _sig_off
-
-    def set_from_int_doctest(self, value):
-        r"""
-        This method exists solely for automated testing of set_from_int().
-
-        sage: x = ntl.ZZ()
-        sage: x.set_from_int_doctest(42)
-        sage: x
-         42
-        """
-        self.set_from_int(int(value))
-
-    # todo: add wrapper for int_to_ZZ in wrap.cc?
-    
-def unpickle_class_value(cls, x):
-    return cls(x)
-
-def unpickle_class_args(cls, x):
-    return cls(*x)
-
-# Random-number generation 
-def ntl_setSeed(x=None):
-    """
-    Seed the NTL random number generator.
-
-    EXAMPLE:
-        sage: ntl.ntl_setSeed(10)
-        sage: ntl.ZZ_random(1000)
-        776
-    """
-    cdef ntl_ZZ seed = ntl_ZZ(1)
-    if x is None:
-        from random import randint
-        seed = ntl_ZZ(str(randint(0,int(2)**64)))
-    else:
-        seed = ntl_ZZ(str(x))
-    _sig_on
-    setSeed(&seed.x)
-    _sig_off
-
-ntl_setSeed()
-
-
-def randomBnd(q):
-    r""" 
-    Returns cryptographically-secure random number in the range [0,n)
-    
-    EXAMPLES:
-        sage: [ntl.ZZ_random(99999) for i in range(5)]
-        [53357, 19674, 69528, 87029, 28752]
-
-    AUTHOR: 
-        -- Didier Deshommes <dfdeshom@gmail.com>
-    """
-    cdef ntl_ZZ w
-
-    if not PY_TYPE_CHECK(q, ntl_ZZ):
-        q = ntl_ZZ(str(q))
-    w = q
-    _sig_on
-    return  make_ZZ(ZZ_randomBnd(&w.x))
-
-def randomBits(long n):
-    r"""
-    Return a pseudo-random number between 0 and $2^n-1$
-
-    EXAMPLES:
-        sage: [ntl.ZZ_random_bits(20) for i in range(3)]
-        [1025619, 177635, 766262]
-        
-    AUTHOR:
-        -- Didier Deshommes <dfdeshom@gmail.com>
-    """
-    _sig_on 
-    return make_ZZ(ZZ_randomBits(n))
Index: age/libs/ntl/ntl_ZZX.pxd
===================================================================
--- sage/libs/ntl/ntl_ZZX.pxd	(revision 6418)
+++ 	(revision )
@@ -1,7 +1,0 @@
-include "decl.pxi"
-include "../../ext/cdefs.pxi"
-
-cdef class ntl_ZZX:
-    cdef ZZX_c x
-    cdef void setitem_from_int(ntl_ZZX self, long i, int value)
-    cdef int getitem_as_int(ntl_ZZX self, long i)
Index: age/libs/ntl/ntl_ZZX.pyx
===================================================================
--- sage/libs/ntl/ntl_ZZX.pyx	(revision 6432)
+++ 	(revision )
@@ -1,1062 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2005 William Stein <wstein@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/
-#*****************************************************************************
-
-include "../../ext/interrupt.pxi"
-include "../../ext/stdsage.pxi"
-include 'misc.pxi'
-include 'decl.pxi'
-
-from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ
-from sage.libs.ntl.ntl_ZZ import unpickle_class_value
-
-from sage.rings.integer import Integer
-from sage.rings.integer_ring import IntegerRing
-from sage.rings.integer cimport Integer
-from sage.rings.integer_ring cimport IntegerRing_class
-
-ZZ = IntegerRing()
-
-cdef make_ZZ(ZZ_c* x):
-    """ These make_XXXX functions are deprecated and should be phased out."""
-    cdef ntl_ZZ y
-    y = ntl_ZZ()
-    y.x = x[0]
-    ZZ_delete(x)
-    _sig_off
-    return y
-
-cdef make_ZZX(ZZX_c* x):
-    """ These make_XXXX functions are deprecated and should be phased out."""
-    cdef ntl_ZZX y
-    _sig_off
-    y = ntl_ZZX()
-    y.x = x[0]
-    ZZX_delete(x)
-    return y
-
-from sage.structure.proof.proof import get_flag
-cdef proof_flag(t):
-    return get_flag(t, "polynomial")
-
-##############################################################################
-#
-# ZZX: polynomials over the integers
-#
-##############################################################################
-
-
-cdef class ntl_ZZX:
-    r"""
-    The class \class{ZZX} implements polynomials in $\Z[X]$, i.e.,
-    univariate polynomials with integer coefficients.
-    
-    Polynomial multiplication is very fast, and is implemented using
-    one of 4 different algorithms:
-    \begin{enumerate}
-    \item\hspace{1em} Classical
-    \item\hspace{1em} Karatsuba
-    \item\hspace{1em} Schoenhage and Strassen --- performs an FFT by working
-          modulo a "Fermat number" of appropriate size...
-          good for polynomials with huge coefficients
-          and moderate degree
-    \item\hspace{1em} CRT/FFT --- performs an FFT by working modulo several
-         small primes.  This is good for polynomials with moderate
-         coefficients and huge degree.
-    \end{enumerate}
-    
-    The choice of algorithm is somewhat heuristic, and may not always be
-    perfect.
-      
-    Many thanks to Juergen Gerhard {\tt
-    <jngerhar@plato.uni-paderborn.de>} for pointing out the deficiency
-    in the NTL-1.0 ZZX arithmetic, and for contributing the
-    Schoenhage/Strassen code.
-    
-    Extensive use is made of modular algorithms to enhance performance
-    (e.g., the GCD algorithm and many others).
-    """
-
-    # See ntl_ZZX.pxd for definition of data members
-    def __init__(self, v=None):
-        """
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,5,-9])
-            sage: f
-            [1 2 5 -9]
-            sage: g = ntl.ZZX([0,0,0]); g
-            []
-            sage: g[10]=5
-            sage: g
-            [0 0 0 0 0 0 0 0 0 0 5]
-            sage: g[10]
-            5
-        """
-        cdef ntl_ZZ cc
-        cdef Py_ssize_t i
-
-        if v is None:
-            return
-        elif PY_TYPE_CHECK(v, list) or PY_TYPE_CHECK(v, tuple):
-            for i from 0 <= i < len(v):
-                x = v[i]
-                if not PY_TYPE_CHECK(x, ntl_ZZ):
-                    cc = ntl_ZZ(x)
-                else:
-                    cc = x
-                ZZX_SetCoeff(self.x, i, cc.x)
-        else:
-            v = str(v)
-            ZZX_from_str(&self.x, v)
-
-    def __reduce__(self):
-        """
-        sage: from sage.libs.ntl.ntl_ZZX import ntl_ZZX
-        sage: f = ntl_ZZX([1,2,0,4])
-        sage: loads(dumps(f)) == f
-        True
-        """
-        return unpickle_class_value, (ntl_ZZX, self.list())
-
-    def __new__(self, v=None):
-        ZZX_construct(&self.x)
-
-    def __dealloc__(self):
-        ZZX_destruct(&self.x)
-
-    def __repr__(self):
-        return str(ZZX_repr(&self.x))
-
-    def copy(self):
-        _sig_on
-        return make_ZZX(ZZX_copy(&self.x))
-
-    def __copy__(self):
-        return make_ZZX(ZZX_copy(&self.x))
-
-    def __setitem__(self, long i, a):
-        """
-            sage: n=ntl.ZZX([1,2,3])
-            sage: n
-            [1 2 3]
-            sage: n[1] = 4
-            sage: n
-            [1 4 3]
-        """
-        if i < 0:
-            raise IndexError, "index (i=%s) must be >= 0"%i
-        cdef ntl_ZZ cc
-        if PY_TYPE_CHECK(a, ntl_ZZ):
-            cc = a
-        else:
-            cc = ntl_ZZ(a)
-        ZZX_SetCoeff(self.x, i, cc.x)
-
-    cdef void setitem_from_int(ntl_ZZX self, long i, int value):
-        r"""
-        Sets ith coefficient to value.
-
-        AUTHOR: David Harvey (2006-08-05)
-        """
-        ZZX_setitem_from_int(&self.x, i, value)
-
-    def setitem_from_int_doctest(self, i, value):
-        r"""
-        This method exists solely for automated testing of setitem_from_int().
-
-        sage: x = ntl.ZZX([2, 3, 4])
-        sage: x.setitem_from_int_doctest(5, 42)
-        sage: x
-         [2 3 4 0 0 42]
-        """
-        self.setitem_from_int(int(i), int(value))
-
-    def __getitem__(self, long i):
-        r"""
-        Retrieves coefficient number i as an NTL ZZ.
-
-        sage: x = ntl.ZZX([129381729371289371237128318293718237, 2, -3, 0, 4])
-        sage: x[0]
-         129381729371289371237128318293718237
-        sage: type(x[0])
-         <type 'sage.libs.ntl.ntl_ZZ.ntl_ZZ'>
-        sage: x[1]
-         2
-        sage: x[2]
-         -3
-        sage: x[3]
-         0
-        sage: x[4]
-         4
-        sage: x[5]
-         0
-        """
-        cdef ntl_ZZ r = ntl_ZZ()
-        _sig_on
-        r.x = ZZX_coeff(self.x, <long>i)
-        _sig_off
-        return r
-
-    cdef int getitem_as_int(ntl_ZZX self, long i):
-        r"""
-        Returns ith coefficient as C int.
-        Return value is only valid if the result fits into an int.
-
-        AUTHOR: David Harvey (2006-08-05)
-        """        
-        return ZZX_getitem_as_int(&self.x, i)
-
-    def getitem_as_int_doctest(self, i):
-        r"""
-        This method exists solely for automated testing of getitem_as_int().
-
-        sage: x = ntl.ZZX([2, 3, 5, -7, 11])
-        sage: i = x.getitem_as_int_doctest(3)
-        sage: print i
-         -7
-        sage: print type(i)
-         <type 'int'>
-        sage: print x.getitem_as_int_doctest(15)
-         0
-        """
-        return self.getitem_as_int(i)
-
-    def list(self):
-        r"""
-        Retrieves coefficients as a list of ntl.ZZ Integers.
-
-        EXAMPLES:
-            sage: x = ntl.ZZX([129381729371289371237128318293718237, 2, -3, 0, 4])
-            sage: L = x.list(); L
-            [129381729371289371237128318293718237, 2, -3, 0, 4]
-            sage: type(L[0])
-            <type 'sage.libs.ntl.ntl_ZZ.ntl_ZZ'>
-            sage: x = ntl.ZZX()
-            sage: L = x.list(); L
-            []
-        """
-        cdef int i
-        return [self[i] for i from 0 <= i <= ZZX_deg(self.x)]
-
-    def __add__(ntl_ZZX self, ntl_ZZX other):
-        """
-        EXAMPLES:
-            sage: ntl.ZZX(range(5)) + ntl.ZZX(range(6))
-            [0 2 4 6 8 5]
-        """
-        cdef ntl_ZZX r = PY_NEW(ntl_ZZX)
-        if not PY_TYPE_CHECK(self, ntl_ZZX):
-            self = ntl_ZZX(self)
-        if not PY_TYPE_CHECK(other, ntl_ZZX):
-            other = ntl_ZZX(other)
-        add_ZZX(r.x, (<ntl_ZZX>self).x, (<ntl_ZZX>other).x)
-        return r
-
-    def __sub__(ntl_ZZX self, ntl_ZZX other):
-        """
-        EXAMPLES:
-            sage: ntl.ZZX(range(5)) - ntl.ZZX(range(6))
-            [0 0 0 0 0 -5]
-        """
-        cdef ntl_ZZX r = PY_NEW(ntl_ZZX)
-        if not PY_TYPE_CHECK(self, ntl_ZZX):
-            self = ntl_ZZX(self)
-        if not PY_TYPE_CHECK(other, ntl_ZZX):
-            other = ntl_ZZX(other)
-        sub_ZZX(r.x, (<ntl_ZZX>self).x, (<ntl_ZZX>other).x)
-        return r
-
-    def __mul__(ntl_ZZX self, ntl_ZZX other):
-        """
-        EXAMPLES:
-            sage: ntl.ZZX(range(5)) * ntl.ZZX(range(6))
-            [0 0 1 4 10 20 30 34 31 20]
-        """
-        cdef ntl_ZZX r = PY_NEW(ntl_ZZX)
-        if not PY_TYPE_CHECK(self, ntl_ZZX):
-            self = ntl_ZZX(self)
-        if not PY_TYPE_CHECK(other, ntl_ZZX):
-            other = ntl_ZZX(other)
-        _sig_on
-        mul_ZZX(r.x, (<ntl_ZZX>self).x, (<ntl_ZZX>other).x)
-        _sig_off
-        return r
-
-    def __div__(ntl_ZZX self, ntl_ZZX other):
-        """
-        Compute quotient self / other, if the quotient is a polynomial.
-        Otherwise an Exception is raised.
-        
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])**2
-            sage: g = ntl.ZZX([4,5])
-            sage: f/g
-            [4 13 22 15]
-            sage: ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])
-            [4 13 22 15]
-
-            sage: f = ntl.ZZX(range(10)); g = ntl.ZZX([-1,0,1])
-            sage: f/g
-            Traceback (most recent call last):
-            ...
-            ArithmeticError: self (=[0 1 2 3 4 5 6 7 8 9]) is not divisible by other (=[-1 0 1])
-        """
-        _sig_on
-        cdef int divisible
-        cdef ZZX_c* q
-        q = ZZX_div(&self.x, &other.x, &divisible)
-        if not divisible:
-            raise ArithmeticError, "self (=%s) is not divisible by other (=%s)"%(self, other)
-        return make_ZZX(q)
-
-    def __mod__(ntl_ZZX self, ntl_ZZX other):
-        """
-        Given polynomials a, b in ZZ[X], there exist polynomials q, r
-        in QQ[X] such that a = b*q + r, deg(r) < deg(b).  This
-        function returns q if q lies in ZZ[X], and otherwise raises an
-        Exception.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([2,4,6]); g = ntl.ZZX([2])
-            sage: f % g   # 0
-            []
-
-            sage: f = ntl.ZZX(range(10)); g = ntl.ZZX([-1,0,1])
-            sage: f % g
-            [20 25]
-        """
-        _sig_on
-        return make_ZZX(ZZX_mod(&self.x, &other.x))
-
-    def quo_rem(self, ntl_ZZX other):
-        """
-        Returns the unique integral q and r such that self = q*other +
-        r, if they exist.  Otherwise raises an Exception.
-
-        EXAMPLES:
-           sage: f = ntl.ZZX(range(10)); g = ntl.ZZX([-1,0,1])
-           sage: q, r = f.quo_rem(g)
-           sage: q, r
-           ([20 24 18 21 14 16 8 9], [20 25])
-           sage: q*g + r == f
-           True
-        """
-        cdef ZZX_c *r, *q
-        _sig_on
-        ZZX_quo_rem(&self.x, &other.x, &r, &q)
-        return (make_ZZX(q), make_ZZX(r))
-
-    def square(self):
-        """
-        Return f*f.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([-1,0,1])
-            sage: f*f
-            [1 0 -2 0 1]
-        """
-        _sig_on
-        return make_ZZX(ZZX_square(&self.x))
-
-    def __pow__(ntl_ZZX self, long n, ignored):
-        """
-        Return the n-th nonnegative power of self.
-
-        EXAMPLES:
-            sage: g = ntl.ZZX([-1,0,1])
-            sage: g**10
-            [1 0 -10 0 45 0 -120 0 210 0 -252 0 210 0 -120 0 45 0 -10 0 1]
-        """
-        if n < 0:
-            raise NotImplementedError
-        import sage.rings.arith
-        return sage.rings.arith.generic_power(self, n, one_ZZX.copy())
-
-    def __cmp__(ntl_ZZX self, ntl_ZZX other):
-        """
-        Decide whether or not self and other are equal.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,3])
-            sage: g = ntl.ZZX([1,2,3,0])
-            sage: f == g
-            True
-            sage: g = ntl.ZZX([0,1,2,3])
-            sage: f == g
-            False
-        """
-        if ZZX_equal(&self.x, &other.x):
-            return 0
-        return -1
-
-    def is_zero(self):
-        """
-        Return True exactly if this polynomial is 0.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([0,0,0,0])
-            sage: f.is_zero()
-            True
-            sage: f = ntl.ZZX([0,0,1])
-            sage: f
-            [0 0 1]
-            sage: f.is_zero()
-            False
-        """
-        return bool(ZZX_is_zero(&self.x))
-
-    def is_one(self):
-        """
-        Return True exactly if this polynomial is 1.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,1])
-            sage: f.is_one()
-            False
-            sage: f = ntl.ZZX([1])
-            sage: f.is_one()
-            True
-        """
-        return bool(ZZX_is_one(&self.x))
-
-    def is_monic(self):
-        """
-        Return True exactly if this polynomial is monic.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([2,0,0,1])
-            sage: f.is_monic()
-            True
-            sage: g = f.reverse()
-            sage: g.is_monic()
-            False
-            sage: g
-            [1 0 0 2]
-        """
-        if ZZX_is_zero(&self.x):
-             return False
-        return bool(ZZ_is_one(ZZX_leading_coefficient(&self.x)))
-
-        # return bool(ZZX_is_monic(&self.x))
-
-    def __neg__(self):
-        """
-        Return the negative of self.
-        EXAMPLES:
-            sage: f = ntl.ZZX([2,0,0,1])
-            sage: -f
-            [-2 0 0 -1]
-        """
-        return make_ZZX(ZZX_neg(&self.x))
-
-    def left_shift(self, long n):
-        """
-        Return the polynomial obtained by shifting all coefficients of
-        this polynomial to the left n positions.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([2,0,0,1])
-            sage: f
-            [2 0 0 1]
-            sage: f.left_shift(2)
-            [0 0 2 0 0 1]
-            sage: f.left_shift(5)
-            [0 0 0 0 0 2 0 0 1]
-
-        A negative left shift is a right shift.
-            sage: f.left_shift(-2)
-            [0 1]
-        """
-        return make_ZZX(ZZX_left_shift(&self.x, n))
-        
-    def right_shift(self, long n):
-        """
-        Return the polynomial obtained by shifting all coefficients of
-        this polynomial to the right n positions.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([2,0,0,1])
-            sage: f
-            [2 0 0 1]
-            sage: f.right_shift(2)
-            [0 1]
-            sage: f.right_shift(5)
-            []
-            sage: f.right_shift(-2)
-            [0 0 2 0 0 1]
-        """
-        return make_ZZX(ZZX_right_shift(&self.x, n))
-
-    def content(self):
-        """
-        Return the content of f, which has sign the same as the
-        leading coefficient of f.  Also, our convention is that the
-        content of 0 is 0.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([2,0,0,2])
-            sage: f.content()
-            2
-            sage: f = ntl.ZZX([2,0,0,-2])
-            sage: f.content()
-            -2
-            sage: f = ntl.ZZX([6,12,3,9])
-            sage: f.content()
-            3
-            sage: f = ntl.ZZX([])
-            sage: f.content()
-            0
-        """
-        cdef char* t
-        t = ZZX_content(&self.x)
-        return int(string(t))
-
-    def primitive_part(self):
-        """
-        Return the primitive part of f.  Our convention is that the leading
-        coefficient of the primitive part is nonnegegative, and the primitive
-        part of 0 is 0.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([6,12,3,9])
-            sage: f.primitive_part()
-            [2 4 1 3]
-            sage: f
-            [6 12 3 9]
-            sage: f = ntl.ZZX([6,12,3,-9])
-            sage: f
-            [6 12 3 -9]
-            sage: f.primitive_part()
-            [-2 -4 -1 3]
-            sage: f = ntl.ZZX()
-            sage: f.primitive_part()
-            []
-        """
-        return make_ZZX(ZZX_primitive_part(&self.x))
-
-    def pseudo_quo_rem(self, ntl_ZZX other):
-        r"""
-        Performs pseudo-division: computes q and r with deg(r) <
-        deg(b), and \code{LeadCoeff(b)\^(deg(a)-deg(b)+1) a = b q + r}.
-        Only the classical algorithm is used.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([0,1])
-            sage: g = ntl.ZZX([1,2,3])
-            sage: g.pseudo_quo_rem(f)
-            ([2 3], [1])
-            sage: f = ntl.ZZX([1,1])
-            sage: g.pseudo_quo_rem(f)
-            ([-1 3], [2])
-        """
-        cdef ZZX_c *r, *q
-        _sig_on
-        ZZX_pseudo_quo_rem(&self.x, &other.x, &r, &q)
-        return (make_ZZX(q), make_ZZX(r))
-
-    def gcd(self, ntl_ZZX other):
-        """
-        Return the gcd d = gcd(a, b), where by convention the leading coefficient
-        of d is >= 0.  We use a multi-modular algorithm.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])**2
-            sage: g = ntl.ZZX([1,1,1])**3 * ntl.ZZX([1,2,3])
-            sage: f.gcd(g)
-            [1 2 3]
-            sage: g.gcd(f)
-            [1 2 3]
-        """
-        _sig_on
-        return make_ZZX(ZZX_gcd(&self.x, &other.x))
-
-    def lcm(self, ntl_ZZX other):
-        """
-        Return the least common multiple of self and other.
-        """
-        g = self.gcd(other)
-        return (self*other).quo_rem(g)[0]
-
-    def xgcd(self, ntl_ZZX other, proof=None):
-        """
-        If self and other are coprime over the rationals, return r, s,
-        t such that r = s*self + t*other.  Otherwise return 0.  This
-        is \emph{not} the same as the \sage function on polynomials
-        over the integers, since here the return value r is always an
-        integer.
-            
-        Here r is the resultant of a and b; if r != 0, then this
-        function computes s and t such that: a*s + b*t = r; otherwise
-        s and t are both 0.  If proof = False (*not* the default),
-        then resultant computation may use a randomized strategy that
-        errors with probability no more than $2^{-80}$.  The default is
-        default is proof=None, see proof.polynomial or sage.structure.proof,
-        but the global default is True), then this function may use a
-        randomized strategy that errors with probability no more than
-        $2^{-80}$.
-        
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])**2
-            sage: g = ntl.ZZX([1,1,1])**3 * ntl.ZZX([1,2,3])
-            sage: f.xgcd(g)   # nothing since they are not coprime
-            (0, [], [])
-    
-        In this example the input quadratic polynomials have a common root modulo 13.
-            sage: f = ntl.ZZX([5,0,1])
-            sage: g = ntl.ZZX([18,0,1])
-            sage: f.xgcd(g)
-            (169, [-13], [13])
-        """
-        proof = proof_flag(proof)
-        
-        cdef ZZX_c *s, *t
-        cdef ZZ_c *r 
-        _sig_on
-        ZZX_xgcd(&self.x, &other.x, &r, &s, &t, proof)
-        return (make_ZZ(r), make_ZZX(s), make_ZZX(t))
-
-    def degree(self):
-        """
-        Return the degree of this polynomial.  The degree of the 0
-        polynomial is -1.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([5,0,1])
-            sage: f.degree()
-            2
-            sage: f = ntl.ZZX(range(100))
-            sage: f.degree()
-            99
-            sage: f = ntl.ZZX()
-            sage: f.degree()
-            -1
-            sage: f = ntl.ZZX([1])
-            sage: f.degree()
-            0
-        """
-        return ZZX_deg(self.x)
-
-    def leading_coefficient(self):
-        """
-        Return the leading coefficient of this polynomial.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([3,6,9])
-            sage: f.leading_coefficient()
-            9
-            sage: f = ntl.ZZX()
-            sage: f.leading_coefficient()
-            0
-        """
-        return make_ZZ(ZZX_leading_coefficient(&self.x))
-
-    def constant_term(self):
-        """
-        Return the constant coefficient of this polynomial.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([3,6,9])
-            sage: f.constant_term()
-            3
-            sage: f = ntl.ZZX()
-            sage: f.constant_term()
-            0
-        """
-        cdef char* t
-        t = ZZX_constant_term(&self.x)
-        return int(string(t))
-
-    def set_x(self):
-        """
-        Set this polynomial to the monomial "x".
-
-        EXAMPLES:
-            sage: f = ntl.ZZX()
-            sage: f.set_x()
-            sage: f
-            [0 1]
-            sage: g = ntl.ZZX([0,1])
-            sage: f == g
-            True
-
-        Though f and g are equal, they are not the same objects in memory:
-            sage: f is g
-            False
-            
-        """
-        ZZX_set_x(&self.x)
-
-    def is_x(self):
-        """
-        True if this is the polynomial "x".
-
-        EXAMPLES:
-            sage: f = ntl.ZZX()
-            sage: f.set_x()
-            sage: f.is_x()
-            True
-            sage: f = ntl.ZZX([0,1])
-            sage: f.is_x()
-            True
-            sage: f = ntl.ZZX([1])
-            sage: f.is_x()
-            False
-        """
-        return bool(ZZX_is_x(&self.x))
-
-    def derivative(self):
-        """
-        Return the derivative of this polynomial.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,7,0,13])
-            sage: f.derivative()
-            [7 0 39]
-        """
-        return make_ZZX(ZZX_derivative(&self.x))
-
-    def reverse(self, hi=None):
-        """
-        Return the polynomial obtained by reversing the coefficients
-        of this polynomial.  If hi is set then this function behaves
-        as if this polynomial has degree hi.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,3,4,5])
-            sage: f.reverse()
-            [5 4 3 2 1]
-            sage: f.reverse(hi=10)
-            [0 0 0 0 0 0 5 4 3 2 1]
-            sage: f.reverse(hi=2)
-            [3 2 1]
-            sage: f.reverse(hi=-2)
-            []
-        """
-        if not (hi is None):
-            return make_ZZX(ZZX_reverse_hi(&self.x, int(hi)))
-        else:
-            return make_ZZX(ZZX_reverse(&self.x))
-
-    def truncate(self, long m):
-        """
-        Return the truncation of this polynomial obtained by
-        removing all terms of degree >= m.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,3,4,5])
-            sage: f.truncate(3)
-            [1 2 3]
-            sage: f.truncate(8)
-            [1 2 3 4 5]
-            sage: f.truncate(1)
-            [1]
-            sage: f.truncate(0)
-            []
-            sage: f.truncate(-1)
-            []
-            sage: f.truncate(-5)
-            []
-        """
-        if m <= 0:
-            return zero_ZZX.copy()
-        _sig_on
-        return make_ZZX(ZZX_truncate(&self.x, m))
-
-    def multiply_and_truncate(self, ntl_ZZX other, long m):
-        """
-        Return self*other but with terms of degree >= m removed.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,3,4,5])
-            sage: g = ntl.ZZX([10])
-            sage: f.multiply_and_truncate(g, 2)
-            [10 20]
-            sage: g.multiply_and_truncate(f, 2)
-            [10 20]
-        """
-        if m <= 0:
-            return zero_ZZX.copy()
-        return make_ZZX(ZZX_multiply_and_truncate(&self.x, &other.x, m))
-
-    def square_and_truncate(self, long m):
-        """
-        Return self*self but with terms of degree >= m removed.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,3,4,5])
-            sage: f.square_and_truncate(4)
-            [1 4 10 20]
-            sage: (f*f).truncate(4)
-            [1 4 10 20]
-        """
-        if m < 0:
-            return zero_ZZX.copy()
-        return make_ZZX(ZZX_square_and_truncate(&self.x, m))
-
-    def invert_and_truncate(self, long m):
-        """
-        Compute and return the inverse of self modulo $x^m$.
-        The constant term of self must be 1 or -1.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,3,4,5,6,7])
-            sage: f.invert_and_truncate(20)
-            [1 -2 1 0 0 0 0 8 -23 22 -7 0 0 0 64 -240 337 -210 49]
-            sage: g = f.invert_and_truncate(20)
-            sage: g * f
-            [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -512 1344 -1176 343]
-        """
-        if m < 0:
-            raise ArithmeticError, "m (=%s) must be positive"%m
-        n = self.constant_term()
-        if n != 1 and n != -1:
-            raise ArithmeticError, \
-                  "The constant term of self must be 1 or -1."
-        _sig_on        
-        return make_ZZX(ZZX_invert_and_truncate(&self.x, m))
-        
-    def multiply_mod(self, ntl_ZZX other, ntl_ZZX modulus):
-        """
-        Return self*other % modulus.  The modulus must be monic with
-        deg(modulus) > 0, and self and other must have smaller degree.
-        
-        EXAMPLES:
-            sage: modulus = ntl.ZZX([1,2,0,1])    # must be monic
-            sage: g = ntl.ZZX([-1,0,1])
-            sage: h = ntl.ZZX([3,7,13])
-            sage: h.multiply_mod(g, modulus)
-            [-10 -34 -36]
-        """
-        _sig_on
-        return make_ZZX(ZZX_multiply_mod(&self.x, &other.x, &modulus.x))
-
-    def trace_mod(self, ntl_ZZX modulus):
-        """
-        Return the trace of this polynomial modulus the modulus.
-        The modulus must be monic, and of positive degree degree bigger
-        than the the degree of self.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,0,3])
-            sage: mod = ntl.ZZX([5,3,-1,1,1])
-            sage: f.trace_mod(mod)
-            -37
-        """
-        _sig_on
-        return make_ZZ(ZZX_trace_mod(&self.x, &modulus.x))
-
-    def trace_list(self):
-        """
-        Return the list of traces of the powers $x^i$ of the
-        monomial x modulo this polynomial for i = 0, ..., deg(f)-1.
-        This polynomial must be monic.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,0,3,0,1])
-            sage: f.trace_list()
-            [5, 0, -6, 0, 10]
-
-        The input polynomial must be monic or a ValueError is raised:
-            sage: f = ntl.ZZX([1,2,0,3,0,2])
-            sage: f.trace_list()
-            Traceback (most recent call last):
-            ...
-            ValueError: polynomial must be monic.
-        """
-        if not self.is_monic():
-            raise ValueError, "polynomial must be monic."
-        _sig_on
-        cdef char* t
-        t = ZZX_trace_list(&self.x)
-        return eval(string(t).replace(' ', ','))
-
-    def resultant(self, ntl_ZZX other, proof=None):
-        """
-        Return the resultant of self and other.  If proof = False (the
-        default is proof=None, see proof.polynomial or sage.structure.proof,
-        but the global default is True), then this function may use a
-        randomized strategy that errors with probability no more than
-        $2^{-80}$.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([17,0,1,1])
-            sage: g = ntl.ZZX([34,-17,18,2])
-            sage: f.resultant(g)
-            1345873
-            sage: f.resultant(g, proof=False)
-            1345873
-        """
-        proof = proof_flag(proof)
-        # NOTES: Within a factor of 2 in speed compared to MAGMA.
-        _sig_on
-        return make_ZZ(ZZX_resultant(&self.x, &other.x, proof))
-
-    def norm_mod(self, ntl_ZZX modulus, proof=None):
-        """
-        Return the norm of this polynomial modulo the modulus.  The
-        modulus must be monic, and of positive degree strictly greater
-        than the degree of self.  If proof=False (the default is
-        proof=None, see proof.polynomial or sage.structure.proof, but
-        the global default is proof=True) then it may use a randomized
-        strategy that errors with probability no more than $2^{-80}$.
-
-        EXAMPLE:
-            sage: f = ntl.ZZX([1,2,0,3])
-            sage: mod = ntl.ZZX([-5,2,0,0,1])
-            sage: f.norm_mod(mod)
-            -8846
-
-        The norm is the constant term of the characteristic polynomial.
-            sage: f.charpoly_mod(mod)
-            [-8846 -594 -60 14 1]
-        """
-        proof = proof_flag(proof)        
-        _sig_on
-        return make_ZZ(ZZX_norm_mod(&self.x, &modulus.x, proof))
-
-    def discriminant(self, proof=None):
-        r"""
-        Return the discriminant of self, which is by definition
-        $$
-                (-1)^{m(m-1)/2} {\mbox{\tt resultant}}(a, a')/lc(a),
-        $$      
-        where m = deg(a), and lc(a) is the leading coefficient of a.
-        If proof is False (the default is proof=None, see
-        proof.polynomial or sage.structure.proof, but the global
-        default is proof=True), then this function may use a
-        randomized strategy that errors with probability no more than
-        $2^{-80}$.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,0,3])
-            sage: f.discriminant()
-            -339
-            sage: f.discriminant(proof=False)
-            -339
-        """
-        proof = proof_flag(proof)
-        _sig_on
-        return make_ZZ(ZZX_discriminant(&self.x, proof))
-
-    #def __call__(self, ntl_ZZ a):
-    #    _sig_on
-    #    return make_ZZ(ZZX_polyeval(&self.x, a.x))
-
-    def charpoly_mod(self, ntl_ZZX modulus, proof=None):
-        """
-        Return the characteristic polynomial of this polynomial modulo
-        the modulus.  The modulus must be monic of degree bigger than
-        self. If proof=False (the default is proof=None, see
-        proof.polynomial or sage.structure.proof, but the global
-        default is proof=True), then this function may use a
-        randomized strategy that errors with probability no more than
-        $2^{-80}$.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,0,3])
-            sage: mod = ntl.ZZX([-5,2,0,0,1])
-            sage: f.charpoly_mod(mod)
-            [-8846 -594 -60 14 1]
-
-        """
-        proof = proof_flag(proof)
-        _sig_on
-        return make_ZZX(ZZX_charpoly_mod(&self.x, &modulus.x, proof))
-
-    def minpoly_mod_noproof(self, ntl_ZZX modulus):
-        """
-        Return the minimal polynomial of this polynomial modulo the
-        modulus.  The modulus must be monic of degree bigger than
-        self.  In all cases, this function may use a randomized
-        strategy that errors with probability no more than $2^{-80}$.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([0,0,1])
-            sage: g = f*f
-            sage: f.charpoly_mod(g)
-            [0 0 0 0 1]
-
-        However, since $f^2 = 0$ moduluo $g$, its minimal polynomial
-        is of degree $2$.
-            sage: f.minpoly_mod_noproof(g)
-            [0 0 1]
-        """
-        _sig_on
-        return make_ZZX(ZZX_minpoly_mod(&self.x, &modulus.x))
-
-    def clear(self):
-        """
-        Reset this polynomial to 0.  Changes this polynomial in place.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,3])
-            sage: f
-            [1 2 3]
-            sage: f.clear()
-            sage: f
-            []
-        """
-        ZZX_clear(&self.x)
-
-    def preallocate_space(self, long n):
-        """
-        Pre-allocate spaces for n coefficients.  The polynomial that f
-        represents is unchanged.  This is useful if you know you'll be
-        setting coefficients up to n, so memory isn't re-allocated as
-        the polynomial grows.  (You might save a millisecond with this
-        function.)
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([1,2,3])
-            sage: f.preallocate_space(20)
-            sage: f
-            [1 2 3]
-            sage: f[10]=5  # no new memory is allocated
-            sage: f
-            [1 2 3 0 0 0 0 0 0 0 5]
-        """
-        _sig_on
-        ZZX_preallocate_space(&self.x, n)
-        _sig_off
-
-    def square_free_decomposition(self):
-        """
-        Returns the square-free decomposition of self (a partial
-        factorization into square-free, relatively prime polynomials)
-        as a list of 2-tuples, where the first element in each tuple
-        is a factor, and the second is its exponent.
-        Assumes that self is primitive.
-
-        EXAMPLES:
-            sage: f = ntl.ZZX([0, 1, 2, 1])
-            sage: f.square_free_decomposition()
-            [([0 1], 1), ([1 1], 2)]
-        """
-        cdef ZZX_c** v
-        cdef long* e
-        cdef long i, n
-        _sig_on
-        ZZX_square_free_decomposition(&v, &e, &n, &self.x)
-        _sig_off
-        F = []
-        for i from 0 <= i < n:
-            F.append((make_ZZX(v[i]), e[i]))
-        free(v)
-        free(e)
-        return F
-
-
-one_ZZX = ntl_ZZX([1])
-zero_ZZX = ntl_ZZX()
Index: age/libs/ntl/ntl_ZZ_p.pxd
===================================================================
--- sage/libs/ntl/ntl_ZZ_p.pxd	(revision 6418)
+++ 	(revision )
@@ -1,11 +1,0 @@
-
-include "decl.pxi"
-
-from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class
-
-cdef class ntl_ZZ_p:
-    cdef ZZ_p_c x
-    cdef ntl_ZZ_pContext_class c
-    cdef public int get_as_int(ntl_ZZ_p self)
-    cdef public void set_from_int(ntl_ZZ_p self, int value)
-    cdef ntl_ZZ_p _new(self)
Index: age/libs/ntl/ntl_ZZ_p.pyx
===================================================================
--- sage/libs/ntl/ntl_ZZ_p.pyx	(revision 6424)
+++ 	(revision )
@@ -1,326 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2005 William Stein <wstein@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/
-#*****************************************************************************
-
-include "../../ext/interrupt.pxi"
-include "../../ext/stdsage.pxi"
-include "../../ext/cdefs.pxi"
-include 'misc.pxi'
-include 'decl.pxi'
-
-from sage.rings.integer import Integer
-from sage.rings.integer_ring import IntegerRing
-from sage.rings.integer cimport Integer
-from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ
-from sage.rings.integer cimport Integer
-from sage.rings.integer_ring cimport IntegerRing_class
-
-from sage.libs.ntl.ntl_ZZ import unpickle_class_args
-
-from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class
-from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext
-
-ZZ_sage = IntegerRing()
-
-def set_ZZ_p_modulus(ntl_ZZ p):
-    ntl_ZZ_set_modulus(&p.x)
-
-def ntl_ZZ_p_random():
-    """
-    Return a random number modulo p.
-    """
-    cdef ntl_ZZ_p y = ntl_ZZ_p()
-    _sig_on
-    ZZ_p_random(y.x)
-    _sig_off
-    return y
-
-
-##############################################################################
-#
-# ZZ_p_c: integers modulo p
-#
-##############################################################################
-cdef class ntl_ZZ_p:
-    r"""
-    The \class{ZZ_p} class is used to represent integers modulo $p$.
-    The modulus $p$ may be any positive integer, not necessarily prime.
-    
-    Objects of the class \class{ZZ_p} are represented as a \code{ZZ} in the
-    range $0, \ldots, p-1$.
-
-    Each \class{ZZ_p} contains a pointer of a \class{ZZ_pContext} which 
-    contains pre-computed data for NTL.  These can be explicitly constructed 
-    and passed to the constructor of a \class{ZZ_p} or the \class{ZZ_pContext} 
-    method \code{ZZ_p} can be used to construct a \class{ZZ_p} element.
-
-    This class takes care of making sure that the C++ library NTL global 
-    variable is set correctly before performing any arithmetic.
-    """
-    def __init__(self, v=None, modulus=None):
-        r"""
-        Initializes and NTL integer.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(11))
-            sage: c.ZZ_p(12r)
-            1
-            sage: c.ZZ_p(Integer(95413094))
-            7
-            sage: c.ZZ_p(long(223895239852389582988))
-            5
-            sage: c.ZZ_p('-1')
-            10
-
-        AUTHOR: Joel B. Mohler (2007-06-14)
-        """
-        if PY_TYPE_CHECK( modulus, ntl_ZZ_pContext_class ):
-            self.c = <ntl_ZZ_pContext_class>modulus
-        elif modulus is not None:
-            self.c = <ntl_ZZ_pContext_class>ntl_ZZ_pContext(ntl_ZZ(modulus))
-        else:
-            raise ValueError, "You must specify a modulus when creating a ZZ_p."
-
-        self.c.restore_c()
-
-        cdef ZZ_c temp
-        if v is not None:
-            _sig_on
-            if PY_TYPE_CHECK(v, ntl_ZZ_p):
-                self.x = (<ntl_ZZ_p>v).x
-            elif PyInt_Check(v):
-                self.x = int_to_ZZ_p(v)
-            elif PyLong_Check(v):
-                ZZ_set_pylong(temp, v)
-                self.x = ZZ_to_ZZ_p(temp)
-            elif isinstance(v, Integer):
-                (<Integer>v)._to_ZZ(&temp)
-                self.x = ZZ_to_ZZ_p(temp)
-            else:
-                v = str(v)
-                ZZ_p_from_str(&self.x, v)
-            _sig_off
-
-    def __new__(self, v=None, modulus=None):
-        ZZ_p_construct(&self.x)
-
-    def __dealloc__(self):
-        if <object>self.c is not None:
-            self.c.restore_c()
-        ZZ_p_destruct(&self.x)
-
-    cdef ntl_ZZ_p _new(self):
-        cdef ntl_ZZ_p r
-        r = PY_NEW(ntl_ZZ_p)
-        r.c = self.c
-        return r
-
-    def __reduce__(self):
-        """
-        sage: a = ntl.ZZ_p(4,7)
-        sage: loads(dumps(a)) == a
-        True
-        """
-        return unpickle_class_args, (ntl_ZZ_p, (self.lift(), self.get_modulus_context()))
-
-    def get_modulus_context(self):
-        return self.c
-
-    def __repr__(self):
-        self.c.restore_c()
-        _sig_on
-        return string_delete(ZZ_p_to_str(&self.x))
-
-    def __richcmp__(ntl_ZZ_p self, ntl_ZZ_p other, op):
-        r"""
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(11))
-            sage: c.ZZ_p(12r)==c.ZZ_p(1)
-            True
-            sage: c.ZZ_p(35r)==c.ZZ_p(1)
-            False
-        """
-        self.c.restore_c()
-        if op != 2 and op != 3:
-            raise TypeError, "Integers mod p are not ordered."
-
-        cdef int t
-#        cdef ntl_ZZ_p y
-#        if not isinstance(other, ntl_ZZ_p):
-#            other = ntl_ZZ_p(other)
-#        y = other
-        _sig_on
-        t = ZZ_p_eq(&self.x, &other.x)
-        _sig_off
-        # t == 1 if self == other
-        if op == 2:
-            return t == 1
-        elif op == 3:
-            return t == 0
-
-    def __invert__(ntl_ZZ_p self):
-        r"""
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(11))
-            sage: ~ntl.ZZ_p(2r,modulus=c)
-            6
-        """
-        cdef ntl_ZZ_p r = self._new()
-        _sig_on
-        self.c.restore_c()
-        ZZ_p_inv(r.x, self.x)
-        _sig_off
-        return r
-
-    def __mul__(ntl_ZZ_p self, other):
-        cdef ntl_ZZ_p y
-        cdef ntl_ZZ_p r = self._new()
-        if not PY_TYPE_CHECK(other, ntl_ZZ_p):
-            other = ntl_ZZ_p(other,self.c)
-        elif self.c is not (<ntl_ZZ_p>other).c:
-            raise ValueError, "You can not perform arithmetic with elements of different moduli."
-        y = other
-        self.c.restore_c()
-        ZZ_p_mul(r.x, self.x, y.x)
-        return r
-
-    def __sub__(ntl_ZZ_p self, other):
-        if not PY_TYPE_CHECK(other, ntl_ZZ_p):
-            other = ntl_ZZ_p(other,self.c)
-        elif self.c is not (<ntl_ZZ_p>other).c:
-            raise ValueError, "You can not perform arithmetic with elements of different moduli."
-        cdef ntl_ZZ_p r = self._new()
-        self.c.restore_c()
-        ZZ_p_sub(r.x, self.x, (<ntl_ZZ_p>other).x)
-        return r
-
-    def __add__(ntl_ZZ_p self, other):
-        cdef ntl_ZZ_p y
-        cdef ntl_ZZ_p r = ntl_ZZ_p(modulus=self.c)
-        if not PY_TYPE_CHECK(other, ntl_ZZ_p):
-            other = ntl_ZZ_p(other,modulus=self.c)
-        elif self.c is not (<ntl_ZZ_p>other).c:
-            raise ValueError, "You can not perform arithmetic with elements of different moduli."
-        y = other
-        _sig_on
-        self.c.restore_c()
-        ZZ_p_add(r.x, self.x, y.x)
-        _sig_off
-        return r
-
-    def __neg__(ntl_ZZ_p self):
-        cdef ntl_ZZ_p r = ntl_ZZ_p(modulus=self.c)
-        _sig_on
-        self.c.restore_c()
-        ZZ_p_negate(r.x, self.x)
-        _sig_off
-        return r
-
-    def __pow__(ntl_ZZ_p self, long e, ignored):
-        cdef ntl_ZZ_p r = ntl_ZZ_p(modulus=self.c)
-        _sig_on
-        self.c.restore_c()
-        ZZ_p_power(r.x, self.x, e)
-        _sig_off
-        return r
-
-
-    cdef int get_as_int(ntl_ZZ_p self):
-        r"""
-        Returns value as C int.
-        Return value is only valid if the result fits into an int.
-
-        AUTHOR: David Harvey (2006-08-05)
-        """
-        self.c.restore_c()
-        return ZZ_p_to_int(self.x)
-
-    def get_as_int_doctest(self):
-        r"""
-        This method exists solely for automated testing of get_as_int().
-
-        sage: c=ntl.ZZ_pContext(ntl.ZZ(20)) 
-        sage: x = ntl.ZZ_p(42,modulus=c)
-        sage: i = x.get_as_int_doctest()
-        sage: print i
-        2
-        sage: print type(i)
-         <type 'int'>
-        """
-        self.c.restore_c()
-        return self.get_as_int()
-
-    cdef void set_from_int(ntl_ZZ_p self, int value):
-        r"""
-        Sets the value from a C int.
-
-        AUTHOR: David Harvey (2006-08-05)
-        """
-        self.c.restore_c()
-        self.x = int_to_ZZ_p(value)
-
-    def set_from_int_doctest(self, value):
-        r"""
-        This method exists solely for automated testing of set_from_int().
-
-        sage: c=ntl.ZZ_pContext(ntl.ZZ(20)) 
-        sage: x = ntl.ZZ_p(modulus=c)
-        sage: x.set_from_int_doctest(42)
-        sage: x
-         2
-        """
-        self.c.restore_c()
-        self.set_from_int(int(value))
-        
-    def lift(self):
-        cdef ntl_ZZ r = ntl_ZZ()
-        self.c.restore_c()
-        r.x = rep(self.x)
-        return r
-
-    def modulus(self):
-        r"""
-        Returns the modulus as an NTL ZZ.
-
-        sage: c=ntl.ZZ_pContext(ntl.ZZ(20)) 
-        sage: n=ntl.ZZ_p(2983,c)
-        sage: n.modulus()
-        20
-        """
-        cdef ntl_ZZ r = ntl_ZZ()
-        self.c.restore_c()
-        ZZ_p_modulus( &r.x, &self.x )
-        return r
-
-    def _sage_(self):
-        r"""
-        Returns the value as a sage IntegerModRing.
-
-        sage: c=ntl.ZZ_pContext(ntl.ZZ(20)) 
-        sage: n=ntl.ZZ_p(2983,c)
-        sage: type(n._sage_())
-        <type 'sage.rings.integer_mod.IntegerMod_int'>
-        sage: n
-        3
-
-        AUTHOR: Joel B. Mohler
-        """
-        from sage.rings.integer_mod_ring import IntegerModRing
-
-        cdef ZZ_c rep
-        self.c.restore_c()
-        rep = ZZ_p_rep(self.x)
-        return IntegerModRing(self.modulus().get_as_sage_int())((<IntegerRing_class>ZZ_sage)._coerce_ZZ(&rep))
-
-    # todo: add wrapper for int_to_ZZ_p in wrap.cc?
Index: age/libs/ntl/ntl_ZZ_pContext.pxd
===================================================================
--- sage/libs/ntl/ntl_ZZ_pContext.pxd	(revision 6424)
+++ 	(revision )
@@ -1,7 +1,0 @@
-include "decl.pxi"
-include "../../ext/cdefs.pxi"
-
-cdef class ntl_ZZ_pContext_class:
-    cdef ZZ_pContext_c x
-    cdef void restore_c(self)
-    cdef p
Index: age/libs/ntl/ntl_ZZ_pContext.pyx
===================================================================
--- sage/libs/ntl/ntl_ZZ_pContext.pyx	(revision 6424)
+++ 	(revision )
@@ -1,83 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2005 William Stein <wstein@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/
-#*****************************************************************************
-
-include "../../ext/interrupt.pxi"
-include "../../ext/stdsage.pxi"
-include 'misc.pxi'
-include 'decl.pxi'
-
-ZZ_pContextDict = {}
-
-from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ
-
-
-cdef class ntl_ZZ_pContext_class:
-    def __init__(self, ntl_ZZ v):
-        """
-        EXAMPLES:
-            # You can construct contexts manually.
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(11))
-            sage: n1=c.ZZ_p(12)
-            sage: n1
-            1
-
-            # or You can construct contexts implicitly.
-            sage: n2=ntl.ZZ_p(12, 7)
-            sage: n2
-            5
-            sage: ntl.ZZ_p(2,3)+ntl.ZZ_p(1,3)
-            0
-            sage: n2+n1  # Mismatched moduli:  It will go BOOM!
-            Traceback (most recent call last):
-            ...
-            ValueError: You can not perform arithmetic with elements of different moduli.
-        """
-        pass
-        
-    def __new__(self, ntl_ZZ v):
-        ZZ_pContext_construct_ZZ(&self.x, &v.x)
-        ZZ_pContextDict[repr(v)] = self
-        self.p = v
-
-    def __dealloc__(self):
-        ZZ_pContext_destruct(&self.x)
-
-    def __reduce__(self):
-        """
-        sage: c=ntl.ZZ_pContext(ntl.ZZ(13))
-        sage: loads(dumps(c)) is c
-        True
-        """
-        return ntl_ZZ_pContext, (self.p,)
-
-    def restore(self):
-        self.restore_c()
-
-    cdef void restore_c(self):
-        ZZ_pContext_restore(&self.x)
-
-    def ZZ_p(self,v = None):
-        from ntl_ZZ_p import ntl_ZZ_p
-        return ntl_ZZ_p(v,modulus=self)
-
-    def ZZ_pX(self,v = None):
-        from ntl_ZZ_pX import ntl_ZZ_pX
-        return ntl_ZZ_pX(v,modulus=self)
-        
-def ntl_ZZ_pContext( ntl_ZZ v ):
-    try:
-        return ZZ_pContextDict[repr(v)]
-    except KeyError:
-        return ntl_ZZ_pContext_class(v)
Index: age/libs/ntl/ntl_ZZ_pX.pxd
===================================================================
--- sage/libs/ntl/ntl_ZZ_pX.pxd	(revision 6418)
+++ 	(revision )
@@ -1,11 +1,0 @@
-include "decl.pxi"
-include "../../ext/cdefs.pxi"
-
-from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class
-
-cdef class ntl_ZZ_pX:
-    cdef ZZ_pX_c x
-    cdef ntl_ZZ_pContext_class c
-    cdef void setitem_from_int(ntl_ZZ_pX self, long i, int value)
-    cdef int getitem_as_int(ntl_ZZ_pX self, long i)
-    cdef ntl_ZZ_pX _new(self)
Index: age/libs/ntl/ntl_ZZ_pX.pyx
===================================================================
--- sage/libs/ntl/ntl_ZZ_pX.pyx	(revision 6425)
+++ 	(revision )
@@ -1,1047 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2005 William Stein <wstein@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/
-#*****************************************************************************
-
-include "../../ext/interrupt.pxi"
-include "../../ext/stdsage.pxi"
-include 'misc.pxi'
-include 'decl.pxi'
-
-from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ
-from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p
-from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class
-from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext
-
-from sage.libs.ntl.ntl_ZZ import unpickle_class_args
-
-cdef make_ZZ_p(ZZ_p_c* x, ntl_ZZ_pContext_class ctx):
-    cdef ntl_ZZ_p y
-    _sig_off
-    y = ntl_ZZ_p(modulus = ctx)
-    y.x = x[0]
-    ZZ_p_delete(x)
-    return y
-
-cdef make_ZZ_pX(ZZ_pX_c* x, ntl_ZZ_pContext_class ctx):
-    cdef ntl_ZZ_pX y
-    y = ntl_ZZ_pX(modulus = ctx)
-    y.x = x[0]
-    ZZ_pX_delete(x)
-    _sig_off
-    return y
-
-##############################################################################
-#
-# ZZ_pX  -- polynomials over the integers modulo p
-#
-##############################################################################
-
-cdef class ntl_ZZ_pX:
-    r"""
-    The class \class{ZZ_pX} implements polynomial arithmetic modulo $p$.
-
-    Polynomial arithmetic is implemented using the FFT, combined with
-    the Chinese Remainder Theorem.  A more detailed description of the
-    techniques used here can be found in [Shoup, J. Symbolic
-    Comp. 20:363-397, 1995].
-
-    Small degree polynomials are multiplied either with classical 
-    or Karatsuba algorithms.
-    """
-    # See ntl_ZZ_pX.pxd for definition of data members
-    def __init__(self, v=[], modulus=None):
-        """
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20)) 
-            sage: f = c.ZZ_pX([1,2,5,-9])
-            sage: f
-            [1 2 5 11]
-            sage: g = c.ZZ_pX([0,0,0]); g
-            []
-            sage: g[10]=5
-            sage: g
-            [0 0 0 0 0 0 0 0 0 0 5]
-            sage: g[10]
-            5
-        """
-        if PY_TYPE_CHECK( modulus, ntl_ZZ_pContext_class ):
-            self.c = <ntl_ZZ_pContext_class>modulus
-        elif modulus is not None:
-            self.c = <ntl_ZZ_pContext_class>ntl_ZZ_pContext(ntl_ZZ(modulus))
-        else:
-            raise ValueError, "You must specify a modulus when creating a ZZ_pX."
-
-        self.c.restore_c()
-
-        cdef ntl_ZZ_p cc
-        cdef Py_ssize_t i
-
-        if v is None:
-            return
-        elif PY_TYPE_CHECK(v, list) or PY_TYPE_CHECK(v, tuple):
-            for i from 0 <= i < len(v):
-                x = v[i]
-                if not PY_TYPE_CHECK(x, ntl_ZZ_p):
-                    cc = ntl_ZZ_p(x,self.c)
-                else:
-                    cc = x
-                ZZ_pX_SetCoeff(self.x, i, cc.x)
-        else:
-            s = str(v).replace(',',' ').replace('L','')
-            _sig_on
-            ZZ_pX_from_str(&self.x, s)
-            _sig_off
-
-    def __new__(self, v=[], modulus=None):
-        ZZ_pX_construct(&self.x)
-
-    def __dealloc__(self):
-        if <object>self.c is not None:
-            self.c.restore_c()
-        ZZ_pX_destruct(&self.x)
-
-    cdef ntl_ZZ_pX _new(self):
-        cdef ntl_ZZ_pX r
-        r = PY_NEW(ntl_ZZ_pX)
-        r.c = self.c
-        return r
-
-    def __reduce__(self):
-        """
-        TEST:
-            sage: f = ntl.ZZ_pX([1,2,3,7], 5); f
-            [1 2 3 2]
-            sage: loads(dumps(f)) == f
-            True
-        """
-        return unpickle_class_args, (ntl_ZZ_pX, (self.list(), self.get_modulus_context()))
-
-    def __repr__(self):
-        self.c.restore_c()
-        return str(ZZ_pX_repr(&self.x))
-
-    def __copy__(self):
-        cdef ntl_ZZ_pX r = self._new()
-        self.c.restore_c()
-        r.x = self.x
-        return r
-
-    def copy(self):
-        return self.__copy__()
-        
-    def get_modulus_context(self):
-        return self.c
-
-    def __setitem__(self, long i, a):
-        r"""
-        sage: c=ntl.ZZ_pContext(ntl.ZZ(20)) 
-        sage: x = c.ZZ_pX([2, 3, 4])
-        sage: x[1] = 5
-        sage: x
-        [2 5 4]
-        """
-        if i < 0:
-            raise IndexError, "index (i=%s) must be >= 0"%i
-        cdef ntl_ZZ_p _a
-        _a = ntl_ZZ_p(a,self.c)
-        self.c.restore_c()
-        ZZ_pX_SetCoeff(self.x, i, _a.x)
-
-    cdef void setitem_from_int(ntl_ZZ_pX self, long i, int value):
-        r"""
-        Sets ith coefficient to value.
-
-        AUTHOR: David Harvey (2006-08-05)
-        """
-        self.c.restore_c()
-        ZZ_pX_SetCoeff_long(self.x, i, value)
-
-    def setitem_from_int_doctest(self, i, value):
-        r"""
-        This method exists solely for automated testing of setitem_from_int().
-
-        sage: c=ntl.ZZ_pContext(ntl.ZZ(20)) 
-        sage: x = c.ZZ_pX([2, 3, 4])
-        sage: x.setitem_from_int_doctest(5, 42)
-        sage: x
-         [2 3 4 0 0 2]
-        """
-        self.c.restore_c()
-        self.setitem_from_int(i, value)
-
-    def __getitem__(self, unsigned int i):
-        r"""
-        This method exists solely for automated testing of setitem_from_int().
-
-        sage: c=ntl.ZZ_pContext(ntl.ZZ(20)) 
-        sage: x = c.ZZ_pX([2, 3, 4])
-        sage: x.setitem_from_int_doctest(5, 42)
-        sage: x
-         [2 3 4 0 0 2]
-        """
-        cdef ntl_ZZ_p r
-        _sig_on
-        r = PY_NEW(ntl_ZZ_p)
-        r.c = self.c
-        self.c.restore_c()
-        r.x = ZZ_pX_coeff( self.x, i)
-        _sig_off
-        return r
-
-    cdef int getitem_as_int(ntl_ZZ_pX self, long i):
-        r"""
-        Returns ith coefficient as C int.
-        Return value is only valid if the result fits into an int.
-
-        AUTHOR: David Harvey (2006-08-05)
-        """
-        self.c.restore_c()
-        cdef ZZ_p_c r
-        cdef long l
-        _sig_on
-        r = ZZ_pX_coeff( self.x, i)
-        ZZ_conv_to_long(l, ZZ_p_rep(r))
-        _sig_off
-        return l
-
-    def getitem_as_int_doctest(self, i):
-        r"""
-        This method exists solely for automated testing of getitem_as_int().
-
-        sage: c=ntl.ZZ_pContext(ntl.ZZ(20)) 
-        sage: x = c.ZZ_pX([2, 3, 5, -7, 11])
-        sage: i = x.getitem_as_int_doctest(3)
-        sage: print i
-         13
-        sage: print type(i)
-         <type 'int'>
-        sage: print x.getitem_as_int_doctest(15)
-         0
-        """
-        self.c.restore_c()
-        return self.getitem_as_int(i)
-
-    def list(self):
-        """
-        Return list of entries as a list of ntl_ZZ_p.
-        """
-        self.c.restore_c()
-        cdef Py_ssize_t i
-        return [self[i] for i from 0 <= i <= self.degree()]
-
-    def __add__(ntl_ZZ_pX self, ntl_ZZ_pX other):
-        """
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))
-            sage: c.ZZ_pX(range(5)) + c.ZZ_pX(range(6))
-            [0 2 4 6 8 5]
-        """
-        if self.c is not other.c:
-            raise ValueError, "You can not perform arithmetic with elements of different moduli."
-        cdef ntl_ZZ_pX r = self._new()
-        _sig_on
-        self.c.restore_c()
-        ZZ_pX_add(r.x, self.x, other.x)
-        _sig_off
-        return r
-
-    def __sub__(ntl_ZZ_pX self, ntl_ZZ_pX other):
-        """
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))         
-            sage: c.ZZ_pX(range(5)) - c.ZZ_pX(range(6))
-            [0 0 0 0 0 15]
-        """
-        if self.c is not other.c:
-            raise ValueError, "You can not perform arithmetic with elements of different moduli."
-        cdef ntl_ZZ_pX r = self._new()
-        _sig_on
-        self.c.restore_c()
-        ZZ_pX_sub(r.x, self.x, other.x)
-        _sig_off
-        return r
-
-    def __mul__(ntl_ZZ_pX self, ntl_ZZ_pX other):
-        """
-        EXAMPLES:
-            sage: c1=ntl.ZZ_pContext(ntl.ZZ(20))
-            sage: alpha = c1.ZZ_pX(range(5))
-            sage: beta = c1.ZZ_pX(range(6))
-            sage: alpha * beta
-            [0 0 1 4 10 0 10 14 11]
-            sage: c2=ntl.ZZ_pContext(ntl.ZZ(5))  # we can mix up the moduli
-            sage: x = c2.ZZ_pX([2, 3, 4])
-            sage: x^2
-            [4 2 0 4 1]
-            sage: alpha * beta  # back to the first one and the ntl modulus gets reset correctly
-            [0 0 1 4 10 0 10 14 11]
-        """
-        if self.c is not other.c:
-            raise ValueError, "You can not perform arithmetic with elements of different moduli."
-        cdef ntl_ZZ_pX r = self._new()
-        _sig_on
-        self.c.restore_c()
-        ZZ_pX_mul(r.x, self.x, other.x)
-        _sig_off
-        return r
-
-    def __div__(ntl_ZZ_pX self, ntl_ZZ_pX other):
-        """
-        Compute quotient self / other, if the quotient is a polynomial.
-        Otherwise an Exception is raised.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))         
-            sage: f = c.ZZ_pX([1,2,3]) * c.ZZ_pX([4,5])**2
-            sage: g = c.ZZ_pX([4,5])
-            sage: f/g
-            [4 13 5 15]
-            sage: c.ZZ_pX([1,2,3]) * c.ZZ_pX([4,5])
-            [4 13 5 15]
-
-            sage: f = c.ZZ_pX(range(10)); g = c.ZZ_pX([-1,0,1])
-            sage: f/g
-            Traceback (most recent call last):
-            ...
-            ArithmeticError: self (=[0 1 2 3 4 5 6 7 8 9]) is not divisible by other (=[16 0 1])
-        """
-        if self.c is not other.c:
-            raise ValueError, "You can not perform arithmetic with elements of different moduli."
-        cdef int divisible
-        cdef ntl_ZZ_pX r = self._new()
-        _sig_on
-        self.c.restore_c()
-        divisible = ZZ_pX_divide(r.x, self.x, other.x)
-        _sig_off
-        if not divisible:
-            raise ArithmeticError, "self (=%s) is not divisible by other (=%s)"%(self, other)
-        return r
-
-    def __mod__(ntl_ZZ_pX self, ntl_ZZ_pX other):
-        """
-        Given polynomials a, b in ZZ[X], there exist polynomials q, r
-        in QQ[X] such that a = b*q + r, deg(r) < deg(b).  This
-        function returns q if q lies in ZZ[X], and otherwise raises an
-        Exception.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))         
-            sage: f = c.ZZ_pX([2,4,6]); g = c.ZZ_pX([2])
-            sage: f % g   # 0
-            []
-
-            sage: f = c.ZZ_pX(range(10)); g = c.ZZ_pX([-1,0,1])
-            sage: f % g
-            [3 8]
-        """
-        if self.c is not other.c:
-            raise ValueError, "You can not perform arithmetic with elements of different moduli."
-        cdef ntl_ZZ_pX r = self._new()
-        _sig_on
-        self.c.restore_c()
-        ZZ_pX_rem(r.x, self.x, other.x)
-        _sig_off
-        return r
-
-    def quo_rem(self, ntl_ZZ_pX other):
-        """
-        Returns the unique integral q and r such that self = q*other +
-        r, if they exist.  Otherwise raises an Exception.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))         
-            sage: f = c.ZZ_pX(range(10)); g = c.ZZ_pX([-1,0,1])
-            sage: q, r = f.quo_rem(g)
-            sage: q, r
-            ([3 7 1 4 14 16 8 9], [3 8])
-            sage: q*g + r == f
-            True
-        """
-        if self.c is not other.c:
-            raise ValueError, "You can not perform arithmetic with elements of different moduli."
-        cdef ntl_ZZ_pX r = self._new()
-        cdef ntl_ZZ_pX q = self._new()
-        _sig_on
-        self.c.restore_c()
-        ZZ_pX_DivRem(q.x, r.x, self.x, other.x)
-        _sig_off
-        return q,r
-
-    def square(self):
-        """
-        Return f*f.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))
-            sage: f = c.ZZ_pX([-1,0,1])
-            sage: f*f
-            [1 0 15 0 1]
-        """
-        self.c.restore_c()
-        _sig_on
-        return make_ZZ_pX(ZZ_pX_square(&self.x), self.c)
-
-    def __pow__(ntl_ZZ_pX self, long n, ignored):
-        """
-        Return the n-th nonnegative power of self.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))
-            sage: g = c.ZZ_pX([-1,0,1])
-            sage: g**10
-            [1 0 10 0 5 0 0 0 10 0 8 0 10 0 0 0 5 0 10 0 1]
-        """
-        self.c.restore_c()
-        if n < 0:
-            raise NotImplementedError
-        import sage.rings.arith
-        return sage.rings.arith.generic_power(self, n, ntl_ZZ_pX([1],self.c))
-
-    def __cmp__(ntl_ZZ_pX self, ntl_ZZ_pX other):
-        """
-        Decide whether or not self and other are equal.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))
-            sage: f = c.ZZ_pX([1,2,3])
-            sage: g = c.ZZ_pX([1,2,3,0])
-            sage: f == g
-            True
-            sage: g = c.ZZ_pX([0,1,2,3])
-            sage: f == g
-            False
-        """
-        self.c.restore_c()
-        if ZZ_pX_equal(&self.x, &other.x):
-            return 0
-        return -1
-
-    def is_zero(self):
-        """
-        Return True exactly if this polynomial is 0.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))        
-            sage: f = c.ZZ_pX([0,0,0,20])
-            sage: f.is_zero()
-            True
-            sage: f = c.ZZ_pX([0,0,1])
-            sage: f
-            [0 0 1]
-            sage: f.is_zero()
-            False
-        """
-        self.c.restore_c()
-        return bool(ZZ_pX_is_zero(&self.x))
-
-    def is_one(self):
-        """
-        Return True exactly if this polynomial is 1.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))        
-            sage: f = c.ZZ_pX([1,1])
-            sage: f.is_one()
-            False
-            sage: f = c.ZZ_pX([1])
-            sage: f.is_one()
-            True
-        """
-        self.c.restore_c()
-        return bool(ZZ_pX_is_one(&self.x))
-
-    def is_monic(self):
-        """
-        Return True exactly if this polynomial is monic.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))        
-            sage: f = c.ZZ_pX([2,0,0,1])
-            sage: f.is_monic()
-            True
-            sage: g = f.reverse()
-            sage: g.is_monic()
-            False
-            sage: g
-            [1 0 0 2]
-            sage: f = c.ZZ_pX([1,2,0,3,0,2])
-            sage: f.is_monic()
-            False            
-        """
-        self.c.restore_c()
-        # The following line is what we should have.  However, strangely this is *broken* 
-        # on PowerPC Intel in NTL, so we program around
-        # the problem.  (William Stein)
-        #return bool(ZZ_pX_is_monic(self.x))
-
-        if ZZ_pX_is_zero(&self.x):
-             return False
-        return bool(ZZ_p_is_one(ZZ_pX_leading_coefficient(&self.x)))
-
-    def __neg__(self):
-        """
-        Return the negative of self.
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))
-            sage: f = c.ZZ_pX([2,0,0,1])
-            sage: -f
-            [18 0 0 19]
-        """
-        cdef ntl_ZZ_pX r = self._new()
-        self.c.restore_c()
-        ZZ_pX_negate(r.x, self.x)
-        return r
-
-    def left_shift(self, long n):
-        """
-        Return the polynomial obtained by shifting all coefficients of
-        this polynomial to the left n positions.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))        
-            sage: f = c.ZZ_pX([2,0,0,1])
-            sage: f
-            [2 0 0 1]
-            sage: f.left_shift(2)
-            [0 0 2 0 0 1]
-            sage: f.left_shift(5)
-            [0 0 0 0 0 2 0 0 1]
-
-        A negative left shift is a right shift.
-            sage: f.left_shift(-2)
-            [0 1]
-        """
-        self.c.restore_c()
-        return make_ZZ_pX(ZZ_pX_left_shift(&self.x, n), self.c)
-
-    def right_shift(self, long n):
-        """
-        Return the polynomial obtained by shifting all coefficients of
-        this polynomial to the right n positions.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))        
-            sage: f = c.ZZ_pX([2,0,0,1])
-            sage: f
-            [2 0 0 1]
-            sage: f.right_shift(2)
-            [0 1]
-            sage: f.right_shift(5)
-            []
-            sage: f.right_shift(-2)
-            [0 0 2 0 0 1]
-        """
-        self.c.restore_c()
-        return make_ZZ_pX(ZZ_pX_right_shift(&self.x, n), self.c)
-
-    def gcd(self, ntl_ZZ_pX other):
-        """
-        Return the gcd d = gcd(a, b), where by convention the leading coefficient
-        of d is >= 0.  We uses a multi-modular algorithm.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))        
-            sage: f = c.ZZ_pX([1,2,3]) * c.ZZ_pX([4,5])**2
-            sage: g = c.ZZ_pX([1,1,1])**3 * c.ZZ_pX([1,2,3])
-            sage: f.gcd(g)
-            [6 12 1]
-            sage: g.gcd(f)
-            [6 12 1]
-        """
-        self.c.restore_c()
-        _sig_on
-        return make_ZZ_pX(ZZ_pX_gcd(&self.x, &other.x), self.c)
-
-    def xgcd(self, ntl_ZZ_pX other, plain=True):
-        """
-        Returns r,s,t such that r = s*self + t*other.
-            
-        Here r is the resultant of a and b; if r != 0, then this
-        function computes s and t such that: a*s + b*t = r; otherwise
-        s and t are both 0. 
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))                
-            sage: f = c.ZZ_pX([1,2,3]) * c.ZZ_pX([4,5])**2
-            sage: g = c.ZZ_pX([1,1,1])**3 * c.ZZ_pX([1,2,3])
-            sage: f.xgcd(g)   # nothing since they are not coprime
-            ([6 12 1], [15 13 6 8 7 9], [4 13])
-    
-        In this example the input quadratic polynomials have a common root modulo 13.
-            sage: f = c.ZZ_pX([5,0,1])
-            sage: g = c.ZZ_pX([18,0,1])
-            sage: f.xgcd(g)
-            ([1], [13], [4])
-            """
-        self.c.restore_c()
-        cdef ntl_ZZ_pX s = self._new()
-        cdef ntl_ZZ_pX t = self._new()
-        cdef ntl_ZZ_pX r = self._new()
-        _sig_on
-        if plain:
-            ZZ_pX_PlainXGCD(r.x, s.x, t.x, self.x, other.x)
-        else:
-            ZZ_pX_XGCD(r.x, s.x, t.x, self.x, other.x)
-        _sig_off
-        return (r,s,t)
-
-    def degree(self):
-        """
-        Return the degree of this polynomial.  The degree of the 0
-        polynomial is -1.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))                
-            sage: f = c.ZZ_pX([5,0,1])
-            sage: f.degree()
-            2
-            sage: f = c.ZZ_pX(range(100))
-            sage: f.degree()
-            99
-            sage: f = c.ZZ_pX()
-            sage: f.degree()
-            -1
-            sage: f = c.ZZ_pX([1])
-            sage: f.degree()
-            0
-        """
-        self.c.restore_c()
-        return ZZ_pX_deg(self.x)
-
-    def leading_coefficient(self):
-        """
-        Return the leading coefficient of this polynomial.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))                
-            sage: f = c.ZZ_pX([3,6,9])
-            sage: f.leading_coefficient()
-            9
-            sage: f = c.ZZ_pX()
-            sage: f.leading_coefficient()
-            0
-        """
-        self.c.restore_c()
-        cdef long i
-        i = ZZ_pX_deg(self.x)
-        return self[i]
-
-    def constant_term(self):
-        """
-        Return the constant coefficient of this polynomial.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))        
-            sage: f = c.ZZ_pX([3,6,9])
-            sage: f.constant_term()
-            3
-            sage: f = c.ZZ_pX()
-            sage: f.constant_term()
-            0
-        """
-        self.c.restore_c()
-        return self[0]
-
-    def set_x(self):
-        """
-        Set this polynomial to the monomial "x".
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))                
-            sage: f = c.ZZ_pX()
-            sage: f.set_x()
-            sage: f
-            [0 1]
-            sage: g = c.ZZ_pX([0,1])
-            sage: f == g
-            True
-
-        Though f and g are equal, they are not the same objects in memory:
-            sage: f is g
-            False
-        """
-        self.c.restore_c()
-        ZZ_pX_clear(self.x)
-        ZZ_pX_SetCoeff_long(self.x, 1, 1)
-
-    def is_x(self):
-        """
-        True if this is the polynomial "x".
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))        
-            sage: f = c.ZZ_pX()
-            sage: f.set_x()
-            sage: f.is_x()
-            True
-            sage: f = c.ZZ_pX([0,1])
-            sage: f.is_x()
-            True
-            sage: f = c.ZZ_pX([1])
-            sage: f.is_x()
-            False
-        """
-        return bool(ZZ_pX_is_x(&self.x))
-
-    def derivative(self):
-        """
-        Return the derivative of this polynomial.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))        
-            sage: f = c.ZZ_pX([1,7,0,13])
-            sage: f.derivative()
-            [7 0 19]
-        """
-        return make_ZZ_pX(ZZ_pX_derivative(&self.x), self.c)
-
-    def factor(self, verbose=False):
-        cdef ZZ_pX_c** v
-        cdef long* e
-        cdef long i, n
-        _sig_on
-        ZZ_pX_factor(&v, &e, &n, &self.x, verbose)
-        _sig_off
-        F = []
-        for i from 0 <= i < n:
-            F.append((make_ZZ_pX(v[i], self.c), e[i]))
-        free(v)
-        free(e)
-        return F
-
-    def linear_roots(self):
-        """
-        Assumes that input is monic, and has deg(f) distinct roots.
-        Returns the list of roots.
-        """
-        cdef ZZ_p_c** v
-        cdef long i, n
-        _sig_on
-        ZZ_pX_linear_roots(&v, &n, &self.x)
-        _sig_off
-        F = []
-        for i from 0 <= i < n:
-            F.append(make_ZZ_p(v[i], self.c))
-        free(v)
-        return F
-
-    def reverse(self, hi=None):
-        """
-        Return the polynomial obtained by reversing the coefficients
-        of this polynomial.  If hi is set then this function behaves
-        as if this polynomial has degree hi.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))                
-            sage: f = c.ZZ_pX([1,2,3,4,5])
-            sage: f.reverse()
-            [5 4 3 2 1]
-            sage: f.reverse(hi=10)
-            [0 0 0 0 0 0 5 4 3 2 1]
-            sage: f.reverse(hi=2)
-            [3 2 1]
-            sage: f.reverse(hi=-2)
-            []
-        """
-        if not (hi is None):
-            return make_ZZ_pX(ZZ_pX_reverse_hi(&self.x, int(hi)), self.c)
-        else:
-            return make_ZZ_pX(ZZ_pX_reverse(&self.x), self.c)
-
-    def truncate(self, long m):
-        """
-        Return the truncation of this polynomial obtained by
-        removing all terms of degree >= m.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))                
-            sage: f = c.ZZ_pX([1,2,3,4,5])
-            sage: f.truncate(3)
-            [1 2 3]
-            sage: f.truncate(8)
-            [1 2 3 4 5]
-            sage: f.truncate(1)
-            [1]
-            sage: f.truncate(0)
-            []
-            sage: f.truncate(-1)
-            []
-            sage: f.truncate(-5)
-            []
-        """
-        if m <= 0:
-            return self._new()
-        _sig_on
-        return make_ZZ_pX(ZZ_pX_truncate(&self.x, m), self.c)
-
-    def multiply_and_truncate(self, ntl_ZZ_pX other, long m):
-        """
-        Return self*other but with terms of degree >= m removed.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))        
-            sage: f = c.ZZ_pX([1,2,3,4,5])
-            sage: g = c.ZZ_pX([10])
-            sage: f.multiply_and_truncate(g, 2)
-            [10]
-            sage: g.multiply_and_truncate(f, 2)
-            [10]
-        """
-        if m <= 0:
-            return self._new()
-        return make_ZZ_pX(ZZ_pX_multiply_and_truncate(&self.x, &other.x, m), self.c)
-
-    def square_and_truncate(self, long m):
-        """
-        Return self*self but with terms of degree >= m removed.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))        
-            sage: f = c.ZZ_pX([1,2,3,4,5])
-            sage: f.square_and_truncate(4)
-            [1 4 10]
-            sage: (f*f).truncate(4)
-            [1 4 10]
-        """
-        if m < 0:
-            return self._new()
-        return make_ZZ_pX(ZZ_pX_square_and_truncate(&self.x, m), self.c)
-
-    def invert_and_truncate(self, long m):
-        """
-        Compute and return the inverse of self modulo $x^m$.
-        The constant term of self must be 1 or -1.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))        
-            sage: f = c.ZZ_pX([1,2,3,4,5,6,7])
-            sage: f.invert_and_truncate(20)
-            [1 18 1 0 0 0 0 8 17 2 13 0 0 0 4 0 17 10 9]
-            sage: g = f.invert_and_truncate(20)
-            sage: g * f
-            [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 4 4 3]
-        """
-        if m < 0:
-            raise ArithmeticError, "m (=%s) must be positive"%m
-        n = self.constant_term()
-        if n != ntl_ZZ_p(1,self.c) and n != ntl_ZZ_p(-1,self.c):
-            raise ArithmeticError, \
-                  "The constant term of self must be 1 or -1."
-        _sig_on
-        return make_ZZ_pX(ZZ_pX_invert_and_truncate(&self.x, m), self.c)
-        
-    def multiply_mod(self, ntl_ZZ_pX other, ntl_ZZ_pX modulus):
-        """
-        Return self*other % modulus.  The modulus must be monic with
-        deg(modulus) > 0, and self and other must have smaller degree.
-        
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))        
-            sage: modulus = c.ZZ_pX([1,2,0,1])    # must be monic
-            sage: g = c.ZZ_pX([-1,0,1])
-            sage: h = c.ZZ_pX([3,7,13])
-            sage: h.multiply_mod(g, modulus)
-            [10 6 4]
-        """
-        self.c.restore_c()
-        cdef ntl_ZZ_pX r = self._new()
-        _sig_on
-        ZZ_pX_MulMod(r.x, self.x, other.x, modulus.x)
-        _sig_off
-        return r
-
-    def trace_mod(self, ntl_ZZ_pX modulus):
-        """
-        Return the trace of this polynomial modulus the modulus.
-        The modulus must be monic, and of positive degree degree bigger
-        than the the degree of self.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))                
-            sage: f = c.ZZ_pX([1,2,0,3])
-            sage: mod = c.ZZ_pX([5,3,-1,1,1])
-            sage: f.trace_mod(mod)
-            3
-        """
-        self.c.restore_c()
-        _sig_on
-        return make_ZZ_p(ZZ_pX_trace_mod(&self.x, &modulus.x), self.c)
-
-    def trace_list(self):
-        """
-        Return the list of traces of the powers $x^i$ of the
-        monomial x modulo this polynomial for i = 0, ..., deg(f)-1.
-        This polynomial must be monic.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))                
-            sage: f = c.ZZ_pX([1,2,0,3,0,1])
-            sage: f.trace_list()
-            [5, 0, 14, 0, 10]
-
-        The input polynomial must be monic or a ValueError is raised:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(20))                
-            sage: f = c.ZZ_pX([1,2,0,3,0,2])
-            sage: f.trace_list()
-            Traceback (most recent call last):
-            ...
-            ValueError: polynomial must be monic.
-        """
-        self.c.restore_c()
-        if not self.is_monic():
-            raise ValueError, "polynomial must be monic."
-        _sig_on
-        cdef char* t
-        t = ZZ_pX_trace_list(&self.x)
-        return eval(string(t).replace(' ', ','))
-
-    def resultant(self, ntl_ZZ_pX other):
-        """
-        Return the resultant of self and other.
-        
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))                
-            sage: f = c.ZZ_pX([17,0,1,1])
-            sage: g = c.ZZ_pX([34,-17,18,2])
-            sage: f.resultant(g)
-            0
-        """
-        self.c.restore_c()
-        _sig_on
-        return make_ZZ_p(ZZ_pX_resultant(&self.x, &other.x), self.c)
-
-    def norm_mod(self, ntl_ZZ_pX modulus):
-        """
-        Return the norm of this polynomial modulo the modulus.  The
-        modulus must be monic, and of positive degree strictly greater
-        than the degree of self. 
-
-        EXAMPLE:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))                
-            sage: f = c.ZZ_pX([1,2,0,3])
-            sage: mod = c.ZZ_pX([-5,2,0,0,1])
-            sage: f.norm_mod(mod)
-            11
-
-        The norm is the constant term of the characteristic polynomial.
-            sage: f.charpoly_mod(mod)
-            [11 1 8 14 1]
-        """
-        self.c.restore_c()
-        _sig_on
-        return make_ZZ_p(ZZ_pX_norm_mod(&self.x, &modulus.x), self.c)
-
-    def discriminant(self):
-        r"""
-        Return the discriminant of a=self, which is by definition
-        $$
-                (-1)^{m(m-1)/2} {\mbox{\tt resultant}}(a, a')/lc(a),
-        $$      
-        where m = deg(a), and lc(a) is the leading coefficient of a.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))                
-            sage: f = c.ZZ_pX([1,2,0,3])
-            sage: f.discriminant()
-            1
-        """
-        self.c.restore_c()
-        cdef long m
-        
-        c = ~self.leading_coefficient()
-        m = self.degree()
-        if (m*(m-1)/2) % 2:
-            c = -c
-        return c*self.resultant(self.derivative())
-
-    def charpoly_mod(self, ntl_ZZ_pX modulus):
-        """
-        Return the characteristic polynomial of this polynomial modulo
-        the modulus.  The modulus must be monic of degree bigger than
-        self.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))                
-            sage: f = c.ZZ_pX([1,2,0,3])
-            sage: mod = c.ZZ_pX([-5,2,0,0,1])
-            sage: f.charpoly_mod(mod)
-            [11 1 8 14 1]
-        """
-        self.c.restore_c()
-        _sig_on
-        return make_ZZ_pX(ZZ_pX_charpoly_mod(&self.x, &modulus.x), self.c)
-
-    def minpoly_mod(self, ntl_ZZ_pX modulus):
-        """
-        Return the minimal polynomial of this polynomial modulo the
-        modulus.  The modulus must be monic of degree bigger than
-        self.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))
-            sage: f = c.ZZ_pX([0,0,1])
-            sage: g = f*f
-            sage: f.charpoly_mod(g)
-            [0 0 0 0 1]
-
-        However, since $f^2 = 0$ moduluo $g$, its minimal polynomial
-        is of degree $2$.
-            sage: f.minpoly_mod(g)
-            [0 0 1]
-        """
-        self.c.restore_c()
-        _sig_on
-        return make_ZZ_pX(ZZ_pX_minpoly_mod(&self.x, &modulus.x), self.c)
-
-    def clear(self):
-        """
-        Reset this polynomial to 0.  Changes this polynomial in place.
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))        
-            sage: f = c.ZZ_pX([1,2,3])
-            sage: f
-            [1 2 3]
-            sage: f.clear()
-            sage: f
-            []
-        """
-        self.c.restore_c()
-        ZZ_pX_clear(self.x)
-
-    def preallocate_space(self, long n):
-        """
-        Pre-allocate spaces for n coefficients.  The polynomial that f
-        represents is unchanged.  This is useful if you know you'll be
-        setting coefficients up to n, so memory isn't re-allocated as
-        the polynomial grows.  (You might save a millisecond with this
-        function.)
-
-        EXAMPLES:
-            sage: c=ntl.ZZ_pContext(ntl.ZZ(17))        
-            sage: f = c.ZZ_pX([1,2,3])
-            sage: f.preallocate_space(20)
-            sage: f
-            [1 2 3]
-            sage: f[10]=5  # no new memory is allocated
-            sage: f
-            [1 2 3 0 0 0 0 0 0 0 5]
-        """
-        self.c.restore_c()
-        _sig_on
-        ZZ_pX_preallocate_space(&self.x, n)
-        _sig_off
-
-
-    ## TODO: NTL's ZZ_pX has minpolys of linear recurrence sequences!!!
Index: age/libs/ntl/ntl_mat_GF2E.pxd
===================================================================
--- sage/libs/ntl/ntl_mat_GF2E.pxd	(revision 6418)
+++ 	(revision )
@@ -1,6 +1,0 @@
-include "decl.pxi"
-include "../../ext/cdefs.pxi"
-
-cdef class ntl_mat_GF2E:
-    cdef mat_GF2E_c x
-    cdef long __nrows, __ncols
Index: age/libs/ntl/ntl_mat_GF2E.pyx
===================================================================
--- sage/libs/ntl/ntl_mat_GF2E.pyx	(revision 6427)
+++ 	(revision )
@@ -1,306 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2005 William Stein <wstein@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/
-#*****************************************************************************
-
-##############################################################################
-#
-# ntl_mat_GF2E: Matrices over the GF(2**x) via NTL
-#
-# AUTHORS:
-#  - Martin Albrecht <malb@informatik.uni-bremen.de>
-#    2006-01: initial version (based on cody by William Stein)
-#
-##############################################################################
-
-include "../../ext/interrupt.pxi"
-include "../../ext/stdsage.pxi"
-include 'misc.pxi'
-include 'decl.pxi'
-
-from ntl_GF2E cimport ntl_GF2E
-import ntl_GF2E as ntl_GF2E_module
-from ntl_GF2E import ntl_GF2E_sage
-from ntl_GF2E import ntl_GF2E_modulus
-
-def unpickle_mat_GF2E(nrows, ncols, entries, mod):
-    ntl_GF2E_modulus(mod)
-    return ntl_mat_GF2E(nrows, ncols, entries)
-
-cdef class ntl_mat_GF2E:
-    r"""
-    The \class{mat_GF2E} class implements arithmetic with matrices over $GF(2**x)$.
-    """
-    def __init__(self, nrows=0, ncols=0, v=None):
-        """
-        Constructs a matrix over ntl.GF2E.
-
-        INPUT:
-            nrows -- number of rows
-            ncols -- nomber of columns
-            v     -- either list or Matrix over GF(2**x)
-
-        EXAMPLES:
-            sage: ntl.GF2E_modulus([1,1,0,1,1,0,0,0,1])
-            sage: m=ntl.mat_GF2E(10,10)
-            sage: m=ntl.mat_GF2E(Matrix(GF(2**8, 'a'),10,10))
-            sage: m=ntl.mat_GF2E(10,10,[ntl.GF2E_random() for x in xrange(10*10)])
-        """
-
-        if nrows is _INIT:
-            return
-
-        cdef unsigned long _nrows, _ncols
-
-        import sage.matrix.matrix
-        if sage.matrix.matrix.is_Matrix(nrows):
-            _nrows = nrows.nrows()
-            _ncols = nrows.ncols()
-            v     = nrows.list()
-        else:
-            _nrows = nrows
-            _ncols = ncols
-
-        if not ntl_GF2E_module.__have_GF2E_modulus:
-            raise "NoModulus"
-        cdef unsigned long i, j
-        cdef ntl_GF2E tmp
-
-        mat_GF2E_SetDims(&self.x, _nrows, _ncols)
-        self.__nrows = _nrows
-        self.__ncols = _ncols
-        if v != None:
-            _sig_on
-            for i from 0 <= i < _nrows:
-                for j from 0 <= j < _ncols:
-                    elem = v[i*_ncols+j]
-                    if not isinstance(elem, ntl_GF2E):
-                        tmp=ntl_GF2E(elem)
-                    else:
-                        tmp=elem
-                    mat_GF2E_setitem(&self.x, i, j, &tmp.gf2e_x)
-            _sig_off
-
-    def __new__(self, nrows=0, ncols=0, v=None):
-        mat_GF2E_construct(&self.x)
-
-    def __dealloc__(self):
-        mat_GF2E_destruct(&self.x)
-
-    def __reduce__(self):
-        """
-        EXAMPLES: 
-            sage: ntl.GF2E_modulus([1,1,0,1,1,0,0,0,1])
-            sage: m = ntl.mat_GF2E(5,5,range(25))
-            sage: loads(dumps(m)) == m
-            True
-        """
-        return unpickle_mat_GF2E, (self.__nrows, self.__ncols, self.list(), ntl_GF2E_modulus())
-
-    def __repr__(self):
-        _sig_on
-        return string_delete(mat_GF2E_to_str(&self.x))
-
-    def __mul__(ntl_mat_GF2E self, other):
-        cdef ntl_mat_GF2E y
-        cdef ntl_mat_GF2E r = ntl_mat_GF2E()
-        if not isinstance(other, ntl_mat_GF2E):
-            other = ntl_mat_GF2E(other)
-        y = other
-        _sig_on
-        mat_GF2E_mul(r.x, self.x, y.x)
-        _sig_off
-        return r
-
-    def __sub__(ntl_mat_GF2E self, other):
-        cdef ntl_mat_GF2E y
-        cdef ntl_mat_GF2E r = ntl_mat_GF2E()
-        if not isinstance(other, ntl_mat_GF2E):
-            other = ntl_mat_GF2E(other)
-        y = other
-        _sig_on
-        mat_GF2E_sub(r.x, self.x, y.x)
-        _sig_off
-        return r
-
-    def __add__(ntl_mat_GF2E self, other):
-        cdef ntl_mat_GF2E y
-        cdef ntl_mat_GF2E r = ntl_mat_GF2E()
-        if not isinstance(other, ntl_mat_GF2E):
-            other = ntl_mat_GF2E(other)
-        y = other
-        _sig_on
-        mat_GF2E_add(r.x, self.x, y.x)
-        _sig_off
-        return r
-
-    def __neg__(ntl_mat_GF2E self):
-        cdef ntl_mat_GF2E r = ntl_mat_GF2E()
-        _sig_on
-        mat_GF2E_negate(r.x, self.x)
-        _sig_off
-        return r
-
-    def __pow__(ntl_mat_GF2E self, long e, ignored):
-        cdef ntl_mat_GF2E r = ntl_mat_GF2E()
-        _sig_on
-        mat_GF2E_power(r.x, self.x, e)
-        _sig_off
-        return r
-        
-    def __cmp__(self, other):
-        c = cmp(type(self), type(other))
-        if not c:
-            if (self-other).is_zero():
-                return 0
-            else:
-                return 1
-        else:
-            return c
-
-    def nrows(self):
-        """
-        Number of rows
-        """
-        return self.__nrows
-    
-    def ncols(self):
-        """
-        Number of columns
-        """
-        return self.__ncols
-
-    def __setitem__(self, ij, x):
-        cdef ntl_GF2E y
-        cdef int i, j
-        if not isinstance(x, ntl_GF2E):
-            x = ntl_GF2E(x)
-        y = x
-
-        from sage.rings.integer import Integer
-        if isinstance(ij, tuple) and len(ij) == 2:
-            i, j = ij
-        elif self.ncols()==1 and (isinstance(ij, Integer) or type(ij)==int):
-            i, j = ij,0
-        elif self.nrows()==1 and (isinstance(ij, Integer) or type(ij)==int):
-            i, j = 0,ij
-        else:
-            raise TypeError, 'ij is not a matrix index'
-
-        if i < 0 or i >= self.__nrows or j < 0 or j >= self.__ncols:
-            raise IndexError, "array index out of range"
-        mat_GF2E_setitem(&self.x, i, j, &y.gf2e_x)
-
-    def __getitem__(self, ij):
-        cdef int i, j
-        from sage.rings.integer import Integer
-        if isinstance(ij, tuple) and len(ij) == 2:
-            i, j = ij
-        elif self.ncols()==1 and (isinstance(ij, Integer) or type(ij)==int):
-            i, j = ij,0
-        elif self.nrows()==1 and (isinstance(ij, Integer) or type(ij)==int):
-            i, j = 0,ij
-        else:
-            raise TypeError, 'ij is not a matrix index'
-        if i < 0 or i >= self.__nrows or j < 0 or j >= self.__ncols:
-            raise IndexError, "array index out of range"
-        cdef GF2E_c* elt = mat_GF2E_getitem(&self.x, i+1, j+1)
-        cdef ntl_GF2E r = ntl_GF2E()
-        r.gf2e_x = elt[0]
-        r.gf2x_x = GF2E_rep(r.gf2e_x)
-        GF2E_delete(elt)
-        return r
-
-    def determinant(self):
-        """
-        Returns the determinant.
-        """
-        cdef ntl_GF2E r = ntl_GF2E()
-        _sig_on
-        r.gf2e_x = mat_GF2E_determinant(self.x)
-        _sig_off
-        return r
-
-    def echelon_form(self,ncols=0):
-        """
-        Performs unitary row operations so as to bring this matrix into row echelon
-        form.  If the optional argument \code{ncols} is supplied, stops when first ncols
-        columns are in echelon form.  The return value is the rank (or the
-        rank of the first ncols columns).
-
-        INPUT:
-           ncols -- number of columns to process
-
-        TODO: what is the output; does it return the rank?
-        """
-        cdef long w
-        w = ncols
-        _sig_on
-        return mat_GF2E_gauss(&self.x, w)
-
-    def list(self):
-        """
-        Returns a list of the entries in this matrix
-
-        EXAMPLES:
-            sage: ntl.GF2E_modulus([1,1,0,1,1,0,0,0,1])
-            sage: m = ntl.mat_GF2E(2,2,[ntl.GF2E_random() for x in xrange(2*2)])
-            sage: m.list()                   # random output
-            [[1 0 1 0 1 0 1 1], [0 1 0 0 0 0 1], [0 0 0 1 0 0 1], [1 1 1 0 0 0 0 1]]
-        """
-        return [self[i,j] for i in range(self.__nrows) for j in range(self.__ncols)]
-
-    def is_zero(self):
-        cdef long isZero
-        _sig_on
-        isZero = mat_GF2E_is_zero(&self.x)
-        _sig_off
-        if isZero==0:
-            return False
-        else:
-            return True
-
-    def _sage_(ntl_mat_GF2E self, k=None, cache=None):
-        """
-        Returns a \class{Matrix} over a FiniteField representation
-        of this element.
-
-        INPUT:
-            self  -- \class{mat_GF2E} element
-            k     -- optional GF(2**deg)
-            cache -- optional NTL to SAGE conversion dictionary
-
-        OUTPUT:
-            Matrix over k
-        """
-        if k==None:
-            k = ntl_GF2E_sage()
-        l = []
-        for elem in self.list():
-            l.append(elem._sage_(k, cache))
-
-        from sage.matrix.constructor import Matrix
-        return Matrix(k,self.nrows(),self.ncols(),l)
-
-    def transpose(ntl_mat_GF2E self):
-        """
-        Returns the transposed matrix of self.
-
-        OUTPUT:
-            transposed Matrix
-        """
-        cdef ntl_mat_GF2E r = ntl_mat_GF2E()
-        _sig_on
-        mat_GF2E_transpose(r.x, self.x)
-        _sig_off
-        return r
Index: age/libs/ntl/ntl_mat_ZZ.pxd
===================================================================
--- sage/libs/ntl/ntl_mat_ZZ.pxd	(revision 6418)
+++ 	(revision )
@@ -1,6 +1,0 @@
-include "decl.pxi"
-include "../../ext/cdefs.pxi"
-
-cdef class ntl_mat_ZZ:
-    cdef mat_ZZ_c x
-    cdef long __nrows, __ncols
Index: age/libs/ntl/ntl_mat_ZZ.pyx
===================================================================
--- sage/libs/ntl/ntl_mat_ZZ.pyx	(revision 6425)
+++ 	(revision )
@@ -1,354 +1,0 @@
-#*****************************************************************************
-#       Copyright (C) 2005 William Stein <wstein@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/
-#*****************************************************************************
-
-include "../../ext/interrupt.pxi"
-include "../../ext/stdsage.pxi"
-include 'misc.pxi'
-include 'decl.pxi'
-
-from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ
-from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX
-
-from ntl_ZZ import unpickle_class_args
-
-cdef make_ZZ(ZZ_c* x):
-    cdef ntl_ZZ y
-    y = ntl_ZZ()
-    y.x = x[0]
-    ZZ_delete(x)
-    _sig_off
-    return y
-
-cdef make_mat_ZZ(mat_ZZ_c* x):
-    cdef ntl_mat_ZZ y
-    _sig_off
-    y = ntl_mat_ZZ(_INIT)
-    y.x = x[0]
-    mat_ZZ_delete(x)
-    y.__nrows = mat_ZZ_nrows(&y.x);
-    y.__ncols = mat_ZZ_ncols(&y.x);
-    return y
-
-##############################################################################
-#
-# ntl_mat_ZZ: Matrices over the integers via NTL
-#
-##############################################################################
-
-cdef class ntl_mat_ZZ:
-    # see ntl.pxd for data members
-    r"""
-    The \class{mat_ZZ} class implements arithmetic with matrices over $\Z$.
-    """
-    def __init__(self, nrows=0,  ncols=0, v=None):
-        if nrows == _INIT:
-            return
-        cdef unsigned long i, j
-        cdef ntl_ZZ tmp
-        if nrows == 0 and ncols == 0:
-            return
-        nrows = int(nrows)
-        ncols = int(ncols)
-        mat_ZZ_SetDims(&self.x, nrows, ncols)
-        self.__nrows = nrows
-        self.__ncols = ncols
-        if v != None:
-            for i from 0 <= i < nrows:
-                for j from 0 <= j < ncols:
-                    tmp = ntl_ZZ(v[i*ncols+j])
-                    mat_ZZ_setitem(&self.x, i, j, &tmp.x)
-
-    def __reduce__(self):
-        """
-        TEST:
-            sage: m = ntl.mat_ZZ(3, 2, range(6)); m
-            [[0 1]
-            [2 3]
-            [4 5]
-            ]
-            sage: loads(dumps(m))
-            [[0 1]
-            [2 3]
-            [4 5]
-            ]
-        """
-        return unpickle_class_args, (ntl_mat_ZZ, (self.__nrows, self.__ncols, self.list()))
-
-    def __new__(self, nrows=0,  ncols=0, v=None):
-        mat_ZZ_construct(&self.x)
-
-    def __dealloc__(self):
-        mat_ZZ_destruct(&self.x)
-
-    def __repr__(self):
-        _sig_on
-        return string_delete(mat_ZZ_to_str(&self.x))
-
-    def __mul__(ntl_mat_ZZ self, other):
-        cdef ntl_mat_ZZ r = PY_NEW(ntl_mat_ZZ)
-        if not PY_TYPE_CHECK(self, ntl_mat_ZZ):
-            self = ntl_mat_ZZ(self)
-        if not PY_TYPE_CHECK(other, ntl_mat_ZZ):
-            other = ntl_mat_ZZ(other)
-        _sig_on
-        mat_ZZ_mul(r.x, (<ntl_mat_ZZ>self).x, (<ntl_mat_ZZ>other).x)
-        _sig_off
-        return r
-
-    def __sub__(ntl_mat_ZZ self, other):
-        cdef ntl_mat_ZZ r = PY_NEW(ntl_mat_ZZ)
-        if not PY_TYPE_CHECK(self, ntl_mat_ZZ):
-            self = ntl_mat_ZZ(self)
-        if not PY_TYPE_CHECK(other, ntl_mat_ZZ):
-            other = ntl_mat_ZZ(other)
-        _sig_on
-        mat_ZZ_sub(r.x, (<ntl_mat_ZZ>self).x, (<ntl_mat_ZZ>other).x)
-        _sig_off
-        return r
-
-    def __add__(ntl_mat_ZZ self, other):
-        cdef ntl_mat_ZZ r = PY_NEW(ntl_mat_ZZ)
-        if not PY_TYPE_CHECK(self, ntl_mat_ZZ):
-            self = ntl_mat_ZZ(self)
-        if not PY_TYPE_CHECK(other, ntl_mat_ZZ):
-            other = ntl_mat_ZZ(other)
-        _sig_on
-        mat_ZZ_add(r.x, (<ntl_mat_ZZ>self).x, (<ntl_mat_ZZ>other).x)
-        _sig_off
-        return r
-
-    def __pow__(ntl_mat_ZZ self, long e, ignored):
-        cdef ntl_mat_ZZ r = PY_NEW(ntl_mat_ZZ)
-        _sig_on
-        mat_ZZ_power(r.x, (<ntl_mat_ZZ>self).x, e)
-        _sig_off
-        return r
-
-    def nrows(self):
-        return self.__nrows
-
-    def ncols(self):
-        return self.__ncols
-
-    def __setitem__(self, ij, x):
-        cdef ntl_ZZ y
-        cdef int i, j
-        if not isinstance(x, ntl_ZZ):
-            y = ntl_ZZ(x)
-        else:
-            y = x
-        if not isinstance(ij, tuple) or len(ij) != 2:
-            raise TypeError, 'ij must be a 2-tuple'
-        i, j = int(ij[0]),int(ij[1])
-        if i < 0 or i >= self.__nrows or j < 0 or j >= self.__ncols:
-            raise IndexError, "array index out of range"
-        _sig_on
-        mat_ZZ_setitem(&self.x, i, j, &y.x)
-        _sig_off
-
-    def __getitem__(self, ij):
-        """
-            sage: m = ntl.mat_ZZ(3, 2, range(6))
-            sage: m[0,0]
-            0
-            sage: m[2,1]
-            5
-            sage: m[3,2] #  oops, 0 based
-            Traceback (most recent call last):
-            ...
-            IndexError: array index out of range
-        """
-        cdef int i, j
-        if not isinstance(ij, tuple) or len(ij) != 2:
-            raise TypeError, 'ij must be a 2-tuple'
-        i, j = ij
-        if i < 0 or i >= self.__nrows or j < 0 or j >= self.__ncols:
-            raise IndexError, "array index out of range"
-        return make_ZZ(mat_ZZ_getitem(&self.x, i+1, j+1))
-
-    def list(self):
-        """
-        EXAMPLE: 
-            sage: m = ntl.mat_ZZ(3, 4, range(12)); m
-            [[0 1 2 3]
-            [4 5 6 7]
-            [8 9 10 11]
-            ]
-            sage: m.list()
-            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
-        """
-        cdef int i, j
-        return [make_ZZ(mat_ZZ_getitem(&self.x, i+1, j+1))
-                    for i from 0 <= i < self.__nrows
-                        for j from 0 <= j < self.__ncols]
-
-    def determinant(self, deterministic=True):
-        _sig_on
-        return make_ZZ(mat_ZZ_determinant(&self.x, deterministic))
-
-    def HNF(self, D=None):
-        r"""
-        The input matrix A=self is an n x m matrix of rank m (so n >=
-        m), and D is a multiple of the determinant of the lattice L
-        spanned by the rows of A.  The output W is the Hermite Normal
-        Form of A; that is, W is the unique m x m matrix whose rows
-        span L, such that
-    
-        - W is lower triangular,
-        - the diagonal entries are positive,
-        - any entry below the diagonal is a non-negative number
-          strictly less than the diagonal entry in its column.
-    
-        This is implemented using the algorithm of [P. Domich,
-        R. Kannan and L. Trotter, Math. Oper. Research 12:50-59,
-        1987].
-
-        TIMINGS:
-        NTL isn't very good compared to MAGMA, unfortunately:
-        
-            sage.: import ntl
-            sage.: a=MatrixSpace(Q,200).random_element()    # -2 to 2
-            sage.: A=ntl.mat_ZZ(200,200)
-            sage.: for i in xrange(a.nrows()):
-               ....:     for j in xrange(a.ncols()):
-               ....:         A[i,j] = a[i,j]
-               ....:
-            sage.: time d=A.determinant()
-            Time.: 3.89 seconds
-            sage.: time B=A.HNF(d)
-            Time.: 27.59 seconds
-
-        In comparison, MAGMA does this much more quickly:
-        \begin{verbatim}
-            > A := MatrixAlgebra(Z,200)![Random(-2,2) : i in [1..200^2]];
-            > time d := Determinant(A);
-            Time: 0.710
-            > time H := HermiteForm(A);
-            Time: 3.080
-        \end{verbatim}
-
-        Also, PARI is also faster than NTL if one uses the flag 1 to
-        the mathnf routine.  The above takes 16 seconds in PARI.
-        """
-        cdef ntl_ZZ _D
-        if D == None:
-            _D = self.determinant()
-        else:
-            _D = ntl_ZZ(D)
-        _sig_on
-        return make_mat_ZZ(mat_ZZ_HNF(&self.x, &_D.x))
-
-    def charpoly(self):
-        """
-        EXAMPLES:
-            sage: ntl.mat_ZZ(2,2,[1,2,3,4]).determinant()
-            -2
-        """
-        cdef ntl_ZZX r = ntl_ZZX()
-        _sig_on
-        mat_ZZ_CharPoly(r.x, self.x)
-        _sig_off
-        return r
-
-    def LLL(self, a=3, b=4, return_U=False, verbose=False):
-        r"""
-        Performs LLL reduction of self (puts self in an LLL form).
-
-        self is an m x n matrix, viewed as m rows of n-vectors.  m may
-        be less than, equal to, or greater than n, and the rows need
-        not be linearly independent. self is transformed into an
-        LLL-reduced basis, and the return value is the rank r of self
-        so as det2 (see below).  The first m-r rows of self are zero.
-
-        More specifically, elementary row transformations are
-        performed on self so that the non-zero rows of new-self form
-        an LLL-reduced basis for the lattice spanned by the rows of
-        old-self.  The default reduction parameter is $\delta=3/4$,
-        which means that the squared length of the first non-zero
-        basis vector is no more than $2^{r-1}$ times that of the
-        shortest vector in the lattice.
-
-        det2 is calculated as the \emph{square} of the determinant of
-        the lattice---note that sqrt(det2) is in general an integer
-        only when r = n.
-
-        If return_U is True, a value U is returned which is the
-        transformation matrix, so that U is a unimodular m x m matrix
-        with U * old-self = new-self.  Note that the first m-r rows of
-        U form a basis (as a lattice) for the kernel of old-B.
-        
-        The parameters a and b allow an arbitrary reduction parameter
-        $\delta=a/b$, where $1/4 < a/b \leq 1$, where a and b are positive
-        integers.  For a basis reduced with parameter delta, the
-        squared length of the first non-zero basis vector is no more
-        than $1/(delta-1/4)^{r-1}$ times that of the shortest vector in
-        the lattice.
-
-        The algorithm employed here is essentially the one in Cohen's
-        book: [H. Cohen, A Course in Computational Algebraic Number
-        Theory, Springer, 1993]
-
-        INPUT:
-           a        -- parameter a as described above (default: 3)
-           b        -- parameter b as described above (default: 4)
-           return_U -- return U as described above
-           verbose  -- if True NTL will produce some verbatim messages on
-                       what's going on internally (default: False)
-
-        OUTPUT:
-            (rank,det2,[U]) where rank,det2, and U are as described
-            above and U is an optional return value if return_U is
-            True.
-
-        EXAMPLE:
-            sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9])
-            sage: M.LLL()
-            (2, 54)
-            sage: M
-            [[0 0 0]
-            [2 1 0]
-            [-1 1 3]
-            ]
-            sage: M=ntl.mat_ZZ(4,4,[-6,9,-15,-18,4,-6,10,12,10,-16,18,35,-24,36,-46,-82]); M
-            [[-6 9 -15 -18]
-            [4 -6 10 12]
-            [10 -16 18 35]
-            [-24 36 -46 -82]
-            ]
-            sage: M.LLL()
-            (3, 19140)
-            sage: M
-            [[0 0 0 0]
-            [0 -2 0 0]
-            [-2 1 -5 -6]
-            [0 -1 -7 5]
-            ]
-
-        WARNING: This method modifies self. So after applying this method your matrix
-        will be a vector of vectors.
-        """
-        cdef ZZ_c *det2
-        cdef ntl_mat_ZZ U
-        if return_U:
-            U = PY_NEW(ntl_mat_ZZ)
-            _sig_on
-            rank = int(mat_ZZ_LLL_U(&det2, &self.x, &U.x, int(a), int(b), int(verbose)))
-            _sig_off
-            return rank, make_ZZ(det2), U
-        else:
-            _sig_on
-            rank = int(mat_ZZ_LLL(&det2,&self.x,int(a),int(b),int(verbose)))
-            _sig_off
-            return rank,make_ZZ(det2)
Index: sage/libs/pari/gen.pyx
===================================================================
--- sage/libs/pari/gen.pyx	(revision 6450)
+++ sage/libs/pari/gen.pyx	(revision 6294)
@@ -34,4 +34,5 @@
 import math
 import types
+from sage.misc.misc import xsrange
 import operator
 import sage.structure.element
@@ -4201,9 +4202,4 @@
         return self.new_gen(dirzetak(self.g, t0))
 
-    def idealred(self, I, vdir=0):
-        t0GEN(I); t1GEN(vdir)
-        _sig_on
-        return self.new_gen(ideallllred(self.g, t0, t1, prec))
-
     def idealadd(self, x, y):
         t0GEN(x); t1GEN(y)
@@ -4351,23 +4347,4 @@
         _sig_on
         return P.new_gen(nfisisom(self.g, other.g))
-
-    def nfsubfields(self, d=0):
-        """
-        Find all subfields of degree d of number field nf (all
-        subfields if d is null or omitted). Result is a vector of
-        subfields, each being given by [g,h], where g is an absolute
-        equation and h expresses one of the roots of g in terms of the
-        root x of the polynomial defining nf.
-
-        INPUT:
-            self -- nf number field
-            d -- integer
-        """
-        if d == 0:
-            _sig_on
-            return self.new_gen(subfields0(self.g, <GEN>0))
-        t0GEN(d)
-        _sig_on
-        return self.new_gen(subfields0(self.g, t0))
 
     def rnfcharpoly(self, T, a, v='x'):
@@ -4768,20 +4745,4 @@
         return self.new_gen(adj(self.g)).Mat()
 
-    def qflll(self, long flag=0):
-        """
-        qflll(x,{flag=0}): LLL reduction of the vectors forming the
-        matrix x (gives the unimodular transformation matrix). The
-        columns of x must be linearly independent, unless specified
-        otherwise below. flag is optional, and can be 0: default, 1:
-        assumes x is integral, columns may be dependent, 2: assumes x
-        is integral, returns a partially reduced basis, 4: assumes x
-        is integral, returns [K,I] where K is the integer kernel of x
-        and I the LLL reduced image, 5: same as 4 but x may have
-        polynomial coefficients, 8: same as 0 but x may have
-        polynomial coefficients.
-        """
-        _sig_on
-        return self.new_gen(qflll0(self.g,flag,prec)).Mat()
-              
     def qflllgram(self, long flag=0):
         """
@@ -5712,5 +5673,5 @@
             pass
         if isinstance(s, (types.ListType, types.XRangeType,
-                            types.TupleType, types.GeneratorType)):
+                            types.TupleType, xsrange)):
             v = self.vector(len(s))
             for i, x in enumerate(s):
Index: age/libs/symmetrica/__init__.py
===================================================================
--- sage/libs/symmetrica/__init__.py	(revision 6437)
+++ 	(revision )
@@ -1,1 +1,0 @@
-
Index: age/libs/symmetrica/all.py
===================================================================
--- sage/libs/symmetrica/all.py	(revision 6437)
+++ 	(revision )
@@ -1,99 +1,0 @@
-#from symmetrica import *
-
-from symmetrica import start, end
-
-#kostka
-from symmetrica import kostka_number_symmetrica as kostka_number
-from symmetrica import kostka_tab_symmetrica as kostka_tab
-from symmetrica import kostka_tafel_symmetrica as kostka_tafel
-
-
-#sab
-from symmetrica import dimension_symmetrization_symmetrica as dimension_symmetrization
-from symmetrica import bdg_symmetrica as bdg
-from symmetrica import sdg_symmetrica as sdg
-from symmetrica import odg_symmetrica as odg
-from symmetrica import specht_dg_symmetrica as specht_dg
-from symmetrica import ndg_symmetrica as ndg
-#from symmetrica import glmndg_symmetrica as glmndg
-
-
-#sc
-from symmetrica import chartafel_symmetrica as chartafel
-from symmetrica import charvalue_symmetrica as charvalue
-from symmetrica import kranztafel_symmetrica as kranztafel
-#from symmetrica import c_ijk_sn_symmetrica  as c_ijk_sn
-
-#part
-from symmetrica import strict_to_odd_part_symmetrica as strict_to_odd_part
-from symmetrica import odd_to_strict_part_symmetrica as odd_to_strict
-from symmetrica import q_core_symmetrica as q_core
-from symmetrica import gupta_nm_symmetrica as gupta_nm
-from symmetrica import gupta_tafel_symmetrica as gupta_tafel
-from symmetrica import random_partition_symmetrica as random_partition
-
-
-#schur
-from symmetrica import outerproduct_schur_symmetrica as outerproduct_schur
-from symmetrica import dimension_schur_symmetrica as dimension_schur
-from symmetrica import part_part_skewschur_symmetrica as part_part_skewschur
-from symmetrica import newtrans_symmetrica as newtrans
-from symmetrica import compute_schur_with_alphabet_symmetrica as compute_schur_with_alphabet
-from symmetrica import compute_homsym_with_alphabet_symmetrica as compute_homsym_with_alphabet
-from symmetrica import compute_elmsym_with_alphabet_symmetrica as compute_elmsym_with_alphabet
-from symmetrica import compute_monomial_with_alphabet_symmetrica as compute_monomial_with_alphabet
-from symmetrica import compute_powsym_with_alphabet_symmetrica as compute_powsym_with_alphabet
-from symmetrica import compute_schur_with_alphabet_det_symmetrica as compute_schur_with_alphabet_det
-from symmetrica import part_part_skewschur_symmetrica as part_part_skewschur
-
-from symmetrica import t_SCHUR_MONOMIAL_symmetrica as t_SCHUR_MONOMIAL
-from symmetrica import t_SCHUR_HOMSYM_symmetrica as t_SCHUR_HOMSYM
-from symmetrica import t_SCHUR_POWSYM_symmetrica as t_SCHUR_POWSYM
-from symmetrica import t_SCHUR_ELMSYM_symmetrica as t_SCHUR_ELMSYM
-
-from symmetrica import t_MONOMIAL_SCHUR_symmetrica as t_MONOMIAL_SCHUR
-from symmetrica import t_MONOMIAL_HOMSYM_symmetrica as t_MONOMIAL_HOMSYM
-from symmetrica import t_MONOMIAL_POWSYM_symmetrica as t_MONOMIAL_POWSYM
-from symmetrica import t_MONOMIAL_ELMSYM_symmetrica as t_MONOMIAL_ELMSYM
-
-from symmetrica import t_ELMSYM_SCHUR_symmetrica as t_ELMSYM_SCHUR
-from symmetrica import t_ELMSYM_MONOMIAL_symmetrica as t_ELMSYM_MONOMIAL
-from symmetrica import t_ELMSYM_HOMSYM_symmetrica as t_ELMSYM_HOMSYM
-from symmetrica import t_ELMSYM_POWSYM_symmetrica as t_ELMSYM_POWSYM
-
-from symmetrica import t_HOMSYM_SCHUR_symmetrica as t_HOMSYM_SCHUR
-from symmetrica import t_HOMSYM_MONOMIAL_symmetrica as t_HOMSYM_MONOMIAL
-from symmetrica import t_HOMSYM_POWSYM_symmetrica as t_HOMSYM_POWSYM
-from symmetrica import t_HOMSYM_ELMSYM_symmetrica as t_HOMSYM_ELMSYM
-
-from symmetrica import t_POWSYM_SCHUR_symmetrica as t_POWSYM_SCHUR
-from symmetrica import t_POWSYM_HOMSYM_symmetrica as t_POWSYM_HOMSYM
-from symmetrica import t_POWSYM_ELMSYM_symmetrica as t_POWSYM_ELMSYM
-from symmetrica import t_POWSYM_MONOMIAL_symmetrica as t_POWSYM_MONOMIAL
-
-
-from symmetrica import mult_schur_schur_symmetrica as mult_schur_schur
-from symmetrica import mult_monomial_monomial_symmetrica as mult_monomial_monomial
-
-
-from symmetrica import hall_littlewood_symmetrica as hall_littlewood
-
-from symmetrica import t_POLYNOM_POWER_symmetrica as t_POLYNOM_POWER
-from symmetrica import t_POLYNOM_SCHUR_symmetrica as t_POLYNOM_SCHUR
-from symmetrica import t_POLYNOM_ELMSYM_symmetrica as t_POLYNOM_ELMSYM
-from symmetrica import t_POLYNOM_MONOMIAL_symmetrica as t_POLYNOM_MONOMIAL
-
-#plet
-from symmetrica import plethysm_symmetrica as plethysm
-from symmetrica import schur_schur_plet_symmetrica as schur_schur_plet
-
-#sb
-from symmetrica import mult_schubert_schubert_symmetrica as mult_schubert_schubert
-from symmetrica import t_SCHUBERT_POLYNOM_symmetrica as t_SCHUBERT_POLYNOM
-from symmetrica import t_POLYNOM_SCHUBERT_symmetrica as t_POLYNOM_SCHUBERT
-from symmetrica import mult_schubert_variable_symmetrica as mult_schubert_variable
-from symmetrica import divdiff_perm_schubert_symmetrica as divdiff_perm_schubert
-from symmetrica import scalarproduct_schubert_symmetrica as scalarproduct_schubert
-from symmetrica import divdiff_schubert_symmetrica as divdiff_schubert
-
-start()
Index: age/libs/symmetrica/kostka.pxi
===================================================================
--- sage/libs/symmetrica/kostka.pxi	(revision 6437)
+++ 	(revision )
@@ -1,152 +1,0 @@
-cdef extern from 'symmetrica/def.h':
-    INT kostka_number(OP shape, OP content, OP result)
-    INT kostka_tab(OP shape, OP content, OP result)
-    INT kostka_tafel(OP n, OP result)
-    
-def kostka_number_symmetrica(shape, content):
-    """
-    computes the kostkanumber, i.e. the number of
-    tableaux of given shape, which is a PARTITION object, and
-    of given content, which also is a PARTITION object, or a VECTOR
-    object with INTEGER entries. The
-    result is an INTEGER object, which is freed to an empty
-    object at the beginning. The shape could also be a
-    SKEWPARTITION object, then we compute the number of 
-    skewtableaux of the given shape.
-
-    EXAMPLES:
-        sage: symmetrica.kostka_number([2,1],[1,1,1])
-        2
-        sage: symmetrica.kostka_number([1,1,1],[1,1,1])
-        1
-        sage: symmetrica.kostka_number([3],[1,1,1])
-        1
-    """
-    cdef OP cshape = callocobject(), ccontent = callocobject(), result = callocobject()
-
-    if PyObject_TypeCheck(shape, builtinlist):
-        if PyObject_TypeCheck(shape[0], builtinlist):
-            shape = SkewPartition(shape)
-        else:
-            shape = Partition(shape)
-   
- 
-    if PyObject_TypeCheck(shape, SkewPartition):
-        _op_skew_partition(shape, cshape)
-    else:
-        _op_partition(shape, cshape)
-        
-    _op_partition(content, ccontent)
-
-    kostka_number(ccontent, cshape, result)
-
-    res = _py(result)
-    
-    freeall(cshape)
-    freeall(ccontent)
-    freeall(result)
-    
-
-    return res
-
-def kostka_tab_symmetrica(shape, content):
-    """
-    computes the list of tableaux of given shape
-    and content. shape is a PARTITION object or a 
-    SKEWPARTITION object and
-    content is a PARTITION object or a VECTOR object with
-    INTEGER entries, the result becomes a
-    LIST object whose entries are the computed TABLEAUX
-    object.
-
-    EXAMPLES:
-        sage: symmetrica.kostka_tab([3],[1,1,1])
-        [[[1, 2, 3]]]
-        sage: symmetrica.kostka_tab([2,1],[1,1,1])
-        [[[1, 2], [3]], [[1, 3], [2]]]
-        sage: symmetrica.kostka_tab([1,1,1],[1,1,1])
-        [[[1], [2], [3]]]
-
-    """
-    late_import()
-    
-    cdef OP cshape = callocobject(), ccontent = callocobject(), result = callocobject()
-    cdef INT err
-    
-    if PyObject_TypeCheck(shape, builtinlist):
-        if PyObject_TypeCheck(shape[0], builtinlist):
-            shape = SkewPartition(shape)
-        else:
-            shape = Partition(shape)
-    
-
-    if PyObject_TypeCheck(shape, SkewPartition):
-        _op_skew_partition(shape, cshape)
-    else:
-        _op_partition(shape, cshape)
-
-
-
-    #Check to make sure the content is compatible with the shape.
-         
-    _op_il_vector(content, ccontent)
-
-    err = kostka_tab(cshape, ccontent, result)
-
-    res = _py(result)
-    
-    freeall(cshape)
-    freeall(ccontent)
-    freeall(result)
-    
-
-    return res
-
-def kostka_tafel_symmetrica(n):
-    """
-    Returns the table of Kostka numbers of weight n.
-
-    EXAMPLES:
-    sage: symmetrica.kostka_tafel(1)
-    [1]
-    
-    sage: symmetrica.kostka_tafel(2)
-    [1 0]
-    [1 1]
-
-    sage: symmetrica.kostka_tafel(3)
-    [1 0 0]
-    [1 1 0]
-    [1 2 1]
-
-    sage: symmetrica.kostka_tafel(4)
-    [1 0 0 0 0]
-    [1 1 0 0 0]
-    [1 1 1 0 0]
-    [1 2 1 1 0]
-    [1 3 2 3 1]
-
-    sage: symmetrica.kostka_tafel(5)
-    [1 0 0 0 0 0 0]
-    [1 1 0 0 0 0 0]
-    [1 1 1 0 0 0 0]
-    [1 2 1 1 0 0 0]
-    [1 2 2 1 1 0 0]
-    [1 3 3 3 2 1 0]
-    [1 4 5 6 5 4 1]
-    """
-
-    cdef OP cn = callocobject(), cresult = callocobject()
-
-    _op_integer(n, cn)
-
-    _sig_on
-    kostka_tafel(cn, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cn)
-    freeall(cresult)
-
-    return res
Index: age/libs/symmetrica/part.pxi
===================================================================
--- sage/libs/symmetrica/part.pxi	(revision 6437)
+++ 	(revision )
@@ -1,190 +1,0 @@
-cdef extern from 'symmetrica/def.h':
-    INT strict_to_odd_part(OP s, OP o)
-    INT odd_to_strict_part(OP o, OP s)
-    INT q_core(OP part, OP d,  OP core)
-    INT gupta_nm(OP n, OP m, OP res)
-    INT gupta_tafel(OP max, OP res)
-    INT random_partition(OP nx, OP res)
-    
-def strict_to_odd_part_symmetrica(part):
-    """
-    implements the bijection between strict partitions
-    and partitions with odd parts. input is a VECTOR type partition, the
-    result is a partition of the same weight with only odd parts.
-
-    """
-
-    #Make sure that the partition is strict
-    cdef INT i
-    for i from 0 <= i < len(part)-1:
-        if part[i] == part[i+1]:
-            raise ValueError, "the partition part (= %s) must be strict"%str(part)
-
-    cdef OP cpart, cres
-    anfang()
-    cpart = callocobject()
-    cres = callocobject()
-
-    _op_partition(part, cpart)
-    
-    strict_to_odd_part(cpart, cres)
-
-    res = _py(cres)
-
-    freeall(cpart)
-    freeall(cres)
-    ende()
-
-    return res
-
-def odd_to_strict_part_symmetrica(part):
-    """
-    implements the bijection between partitions with odd parts
-    and strict partitions. input is a VECTOR type partition, the
-    result is a partition of the same weight with different parts.
-    """
-
-    #Make sure that the partition is strict
-    cdef INT i
-    for i from 0 <= i < len(part):
-        if part[i] % 2 == 0:
-            raise ValueError, "the partition part (= %s) must be odd"%str(part)
-
-    cdef OP cpart, cres
-    anfang()
-    cpart = callocobject()
-    cres = callocobject()
-
-    _op_partition(part, cpart)
-    
-    odd_to_strict_part(cpart, cres)
-
-    res = _py(cres)
-
-    freeall(cpart)
-    freeall(cres)
-    ende()
-
-    return res
-
-
-def q_core_symmetrica(part, d):
-    """
-    computes the q-core of a PARTITION object
-    part. This is the remaining partition (=res) after
-    removing of all hooks of length d (= INTEGER object).
-    The result may be an empty object, if the whole
-    partition disappears.
- 
-    """
-    
-
-    cdef OP cpart, cres, cd
-    anfang()
-    cpart = callocobject()
-    cd = callocobject()
-    cres = callocobject()
-
-    _op_partition(part, cpart)
-    _op_integer(d, cd)
-    
-    q_core(cpart, cd, cres)
-
-    res = _py(cres)
-
-    freeall(cpart)
-    freeall(cres)
-    freeall(cd)
-    ende()
-
-    return res
-
-
-def gupta_nm_symmetrica(n, m):
-    """
-    this routine computes the number of partitions
-    of n with maximal part m. The result is erg. The
-    input n,m must be INTEGER objects. The result is
-    freed first to an empty object. The result must
-    be a different from m and n.
-    """
-    
-
-    cdef OP cn, cm, cres
-    anfang()
-    cm = callocobject()
-    cn = callocobject()
-    cres = callocobject()
-
-
-    _op_integer(n, cn)
-    _op_integer(m, cm)
-    
-    gupta_nm(cn, cm, cres)
-
-    res = _py(cres)
-
-    freeall(cn)
-    freeall(cres)
-    freeall(cm)
-    ende()
-
-    return res
-
-def gupta_tafel_symmetrica(max):
-    """
-    it computes the table of the above values. The entry
-    n,m is the result of gupta_nm. mat is freed first. 
-    max must be an INTEGER object, it is the maximum 
-    weight for the partitions. max must be different from
-    result.
-    """
-    
-
-    cdef OP cmax, cres
-    anfang()
-
-    cmax = callocobject()
-    cres = callocobject()
-
-
-    _op_integer(max, cmax)
-    
-    gupta_tafel(cmax, cres)
-
-    res = _py(cres)
-
-    freeall(cmax)
-    freeall(cres)
-    ende()
-
-    return res
-
-
-def random_partition_symmetrica(n):
-    """
-    returns a random partition p of the entered weight w.
-    w must be an INTEGER object, p becomes a PARTITION object.
-    Type of partition is VECTOR . Its the algorithm of
-    Nijnhuis Wilf p.76
-    """
-    
-
-    cdef OP cn, cres
-    anfang()
-
-    cn = callocobject()
-    cres = callocobject()
-
-
-    _op_integer(n, cn)
-    
-    random_partition(cn, cres)
-
-    res = _py(cres)
-
-    freeall(cn)
-    freeall(cres)
-    ende()
-
-    return res
Index: age/libs/symmetrica/plet.pxi
===================================================================
--- sage/libs/symmetrica/plet.pxi	(revision 6437)
+++ 	(revision )
@@ -1,46 +1,0 @@
-cdef extern from 'symmetrica/def.h':
-    INT plethysm(OP s1, OP s2, OP res)
-    INT schur_schur_plet(OP p1, OP p2, OP res)
-
-def plethysm_symmetrica(outer, inner):
-    """
-    """
-
-    cdef OP couter = callocobject(), cinner = callocobject(), cresult = callocobject()
-
-    _op_schur(outer, couter)
-    _op_schur(inner, cinner)
-
-    _sig_on
-    plethysm(couter, cinner, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(couter)
-    freeall(cinner)
-    freeall(cresult)
-
-    return res
-
-
-def schur_schur_plet_symmetrica(outer, inner):
-    """
-    """
-
-    cdef OP couter = callocobject(), cinner = callocobject(), cresult = callocobject()
-
-    _op_partition(outer, couter)
-    _op_partition(inner, cinner)
-
-    _sig_on
-    schur_schur_plet(couter, cinner, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(couter)
-    freeall(cinner)
-    freeall(cresult)
-
-    return res
Index: age/libs/symmetrica/sab.pxi
===================================================================
--- sage/libs/symmetrica/sab.pxi	(revision 6437)
+++ 	(revision )
@@ -1,217 +1,0 @@
-cdef extern from 'symmetrica/def.h':
-    INT dimension_symmetrization(OP n, OP part, OP a)
-    INT bdg(OP part, OP perm, OP D)
-    INT sdg(OP part, OP perm, OP D)
-    INT odg(OP part, OP perm, OP D)
-    INT ndg(OP part, OP perm, OP D)
-    INT specht_dg(OP part, OP perm, OP D)
-    INT glmndg(OP m, OP n, OP M, INT VAR)
-    
-    
-def dimension_symmetrization_symmetrica(n, part):
-    """
-    computes the dimension of the degree of a irreducible
-    representation of the GL_n, n is a INTEGER object, labeled
-    by the PARTITION object a.
-    """
-    cdef OP cn, cpart, cres
-
-    
-    cn    = callocobject()
-    cpart = callocobject()
-    cres  = callocobject()
-
-    _op_partition(part, cpart)
-    _op_integer(n, cn)
-
-    dimension_symmetrization(cn, cpart, cres)
-    res = _py_integer(cres)
-
-    freeall(cn)
-    freeall(cpart)
-    freeall(cres)
-    
-
-    return res
-
-
-def bdg_symmetrica(part, perm):
-    """
-    Calculates the irreduzible matrix representation 
-    D^part(perm), whose entries are of integral numbers.
-
-    REFERENCE: H. Boerner:
-               Darstellungen von Gruppen, Springer 1955.
-               pp. 104-107.
-    """
-    cdef OP cpart, cperm, cD
-
-    
-    cpart = callocobject()
-    cperm = callocobject()
-    cD    = callocobject()
-
-    _op_partition(part, cpart)
-    _op_permutation(perm, cperm)
-
-    bdg(cpart, cperm, cD)
-    res = _py_matrix(cD)
-
-    freeall(cpart)
-    freeall(cperm)
-    freeall(cD)
-    
-
-
-def sdg_symmetrica(part, perm):
-    """
-    
-    Calculates the irreduzible matrix representation 
-    D^part(perm), which consists of rational numbers.
-
-    REFERENCE: G. James/ A. Kerber:  
-               Representation Theory of the Symmetric Group.
-               Addison/Wesley 1981.
-               pp. 124-126.
-    """
-    cdef OP cpart, cperm, cD
-
-    
-    cpart = callocobject()
-    cperm = callocobject()
-    cD    = callocobject()
-
-    _op_partition(part, cpart)
-    _op_permutation(perm, cperm)
-
-    sdg(cpart, cperm, cD)
-    res = _py_matrix(cD)
-
-    freeall(cpart)
-    freeall(cperm)
-    freeall(cD)
-    
-
-    
-    return res
-
-def odg_symmetrica(part, perm):
-    """
-    Calculates the irreduzible matrix representation 
-    D^part(perm), which consists of real numbers.
-
-    REFERENCE: G. James/ A. Kerber:  
-               Representation Theory of the Symmetric Group.
-               Addison/Wesley 1981.
-               pp. 127-129.
-    """
-    cdef OP cpart, cperm, cD
-
-    
-    cpart = callocobject()
-    cperm = callocobject()
-    cD    = callocobject()
-
-    _op_partition(part, cpart)
-    _op_permutation(perm, cperm)
-
-    odg(cpart, cperm, cD)
-    res = _py_matrix(cD)
-
-    freeall(cpart)
-    freeall(cperm)
-    freeall(cD)
-    
-
-    
-    return res
-
-
-def ndg_symmetrica(part, perm):
-    """
- 
-    """
-    cdef OP cpart, cperm, cD
-
-    
-    cpart = callocobject()
-    cperm = callocobject()
-    cD    = callocobject()
-
-    _op_partition(part, cpart)
-    _op_permutation(perm, cperm)
-
-    ndg(cpart, cperm, cD)
-    res = _py_matrix(cD)
-
-    freeall(cpart)
-    freeall(cperm)
-    freeall(cD)
-    
-
-    
-    return res
-
-def specht_dg_symmetrica(part, perm):
-    """
- 
-    """
-    cdef OP cpart, cperm, cD
-
-    
-    cpart = callocobject()
-    cperm = callocobject()
-    cD    = callocobject()
-
-    _op_partition(part, cpart)
-    _op_permutation(perm, cperm)
-
-    specht_dg(cpart, cperm, cD)
-    res = _py_matrix(cD)
-
-    freeall(cpart)
-    freeall(cperm)
-    freeall(cD)
-    
-
-    
-    return res
-
-
-## def glmndg_symmetrica(m, n, VAR=0):
-##     """
-##     If VAR is equal to 0 the orthogonal representation 
-##     is used for the decomposition, otherwise, if VAR 
-##     equals 1, the natural representation is considered.
-
-##     The result is the  VECTOR-Object M, consisting of  
-##     components of type MATRIX, representing the several 
-##     irreducible matrix representations of GLm(C) with 
-##     part_1' <= m, where part is a partition of n.
-
-##     """
-##     cdef OP cm, cn, cM
-    
-##     
-    
-##     cm = callocobject()
-##     _op_integer(m, cm)
-    
-##     cn = callocobject()
-##     _op_integer(n, cn)
-    
-##     cM = callocobject()
-    
-    
-
-##     glmndg(cm, cn, cM, VAR)
-##     res = _py(cM)
-
-
-##    freeall(cm)
-##    freeall(cn)
-##    freeall(cM)
-
-##    
-
-##    return res
Index: age/libs/symmetrica/sb.pxi
===================================================================
--- sage/libs/symmetrica/sb.pxi	(revision 6437)
+++ 	(revision )
@@ -1,211 +1,0 @@
-cdef extern from 'symmetrica/def.h':
-    INT mult_schubert_schubert(OP a, OP b, OP result)
-    INT m_perm_sch(OP a, OP b)
-    INT t_SCHUBERT_POLYNOM(OP a, OP b)
-    INT t_POLYNOM_SCHUBERT(OP a, OP b)
-    INT mult_schubert_variable(OP a, OP i, OP r)
-    INT divdiff_perm_schubert(OP perm, OP sb, OP res)
-    INT scalarproduct_schubert(OP a, OP b, OP c)
-    INT divdiff_schubert(OP a, OP schub, OP res)
-    
-    INT t_2SCHUBERT_POLYNOM(OP a,OP b)
-    INT mult_schubert_polynom(OP a,OP b,OP c)
-
-
-
-
-
-    
-def mult_schubert_schubert_symmetrica(a, b):
-    """
-    Multiplies the Schubert polynomials a and b.
-    """
-    late_import()
-    
-    cdef OP ca = callocobject(), cb = callocobject(), cres = callocobject()
-
-    if isinstance(a, (Permutation_class, builtinlist)) and isinstance(b, (Permutation_class, builtinlist)):
-        _op_schubert_perm(a, ca)
-        _op_schubert_perm(b, cb)
-    else:
-        ab = a.parent().base_ring()
-        bb = b.parent().base_ring()
-        if ab == bb and (ab == QQ or ab == ZZ):
-            _op_schubert_sp(a, ca)
-            _op_schubert_sp(b, cb)
-        else:
-            raise ValueError, "a and b must be Schubert polynomials over ZZ or QQ"
-
-    _sig_on
-    mult_schubert_schubert(ca, cb, cres)
-    _sig_off
-    
-    res = _py(cres)
-
-    freeall(ca)
-    freeall(cb)
-    freeall(cres)
-
-    return res
-
-def t_SCHUBERT_POLYNOM_symmetrica(a):
-    late_import()
-    
-    cdef OP ca = callocobject(), cres = callocobject()
-
-    if isinstance(a, (Permutation_class, builtinlist)):
-        _op_schubert_perm(a, ca)
-    else:
-        ab = a.parent().base_ring()
-        if (ab == QQ or ab == ZZ):
-            _op_schubert_sp(a, ca)
-        else:
-            raise ValueError, "a and b must be Schubert polynomials over ZZ or QQ"
-        
-
-    _sig_on
-    t_SCHUBERT_POLYNOM(ca, cres)
-    _sig_off
-
-    res = _py(cres)
-
-    freeall(ca)
-    freeall(cres)
-
-    return res
-
-def t_POLYNOM_SCHUBERT_symmetrica(a):
-    cdef OP ca = callocobject(), cres = callocobject()
-
-    _op_polynom(a, ca)
-    
-    _sig_on
-    t_POLYNOM_SCHUBERT(ca, cres)
-    _sig_off
-
-    res = _py(cres)
-
-    freeall(ca)
-    freeall(cres)
-    
-    return res
-
-def mult_schubert_variable_symmetrica(a, i):
-    late_import()
-    
-    cdef OP ca = callocobject(), ci = callocobject(),  cres = callocobject()
-
-    if isinstance(a, (Permutation_class, builtinlist)):
-        _op_schubert_perm(a, ca)
-    else:
-        ab = a.parent().base_ring()
-        if (ab == QQ or ab == ZZ):
-            _op_schubert_sp(a, ca)
-        else:
-            raise ValueError, "a and b must be Schubert polynomials over ZZ or QQ"
-    _op_integer(i, ci)
-
-    _sig_on
-    mult_schubert_variable(ca, ci, cres)
-    _sig_off
-
-    res = _py(cres)
-
-    freeall(ca)
-    freeall(ci)
-    freeall(cres)
-
-    return res
-
-
-def divdiff_perm_schubert_symmetrica(perm, a):
-    late_import()
-    
-    cdef OP ca = callocobject(), cperm = callocobject(),  cres = callocobject()
-
-    if isinstance(a, (Permutation_class, builtinlist)):
-        _op_schubert_perm(a, ca)
-    else:
-        ab = a.parent().base_ring()
-        if (ab == QQ or ab == ZZ):
-            _op_schubert_sp(a, ca)
-        else:
-            raise ValueError, "a and b must be Schubert polynomials over ZZ or QQ"
-    _op_permutation(perm, cperm)
-
-    _sig_on
-    divdiff_perm_schubert(cperm, ca, cres)
-    _sig_off
-
-    res = _py(cres)
-
-    freeall(ca)
-    freeall(cperm)
-    freeall(cres)
-
-    return res
-
-
-def scalarproduct_schubert_symmetrica(a, b):
-    late_import()
-    
-    cdef OP ca = callocobject(), cb = callocobject(), cres = callocobject()
-
-    if isinstance(a, (Permutation_class, builtinlist)) and isinstance(b, (Permutation_class, builtinlist)):
-        _op_schubert_perm(a, ca)
-        _op_schubert_perm(b, cb)
-    else:
-        ab = a.parent().base_ring()
-        bb = b.parent().base_ring()
-        if ab == bb and (ab == QQ or ab == ZZ):
-            _op_schubert_sp(a, ca)
-            _op_schubert_sp(b, cb)
-        else:
-            raise ValueError, "a and b must be Schubert polynomials over ZZ or QQ"
-
-
-    _sig_on
-    scalarproduct_schubert(ca, cb, cres)
-    _sig_off
-
-
-    if empty_listp(cres):
-        freeall(ca)
-        freeall(cb)
-        freeall(cres)
-        return Integer(0)
-    
-    res = _py(cres)
-
-    freeall(ca)
-    freeall(cb)
-    freeall(cres)
-
-    return res
-
-def divdiff_schubert_symmetrica(i, a):
-    late_import()
-    
-    cdef OP ca = callocobject(), ci = callocobject(),  cres = callocobject()
-
-    if isinstance(a, (Permutation_class, builtinlist)):
-        _op_schubert_perm(a, ca)
-    else:
-        ab = a.parent().base_ring()
-        if (ab == QQ or ab == ZZ):
-            _op_schubert_sp(a, ca)
-        else:
-            raise ValueError, "a and b must be Schubert polynomials over ZZ or QQ"
-    _op_integer(i, ci)
-
-    _sig_on
-    divdiff_schubert(ci, ca, cres)
-    _sig_off
-
-    res = _py(cres)
-
-    freeall(ca)
-    freeall(ci)
-    freeall(cres)
-
-    return res
Index: age/libs/symmetrica/sc.pxi
===================================================================
--- sage/libs/symmetrica/sc.pxi	(revision 6437)
+++ 	(revision )
@@ -1,194 +1,0 @@
-cdef extern from 'symmetrica/def.h':
-    INT chartafel(OP degree, OP result)
-    INT charvalue(OP irred, OP cls, OP result, OP table)
-    INT kranztafel(OP a, OP b, OP res, OP co, OP cl)
-    INT c_ijk_sn(OP i, OP j, OP k, OP res)
-
-def chartafel_symmetrica(n):
-    """
-    you enter the degree of the symmetric group, as INTEGER 
-    object and the result is a MATRIX object: the charactertable 
-    of the symmetric group of the given degree.
-
-    EXAMPLES:
-        sage: symmetrica.chartafel(3)
-        [ 1  1  1]
-        [-1  0  2]
-        [ 1 -1  1]
-        sage: symmetrica.chartafel(4)
-        [ 1  1  1  1  1]
-        [-1  0 -1  1  3]
-        [ 0 -1  2  0  2]
-        [ 1  0 -1 -1  3]
-        [-1  1  1 -1  1]
-     """
-    
-    cdef OP cn, cres
-    
-    cn   = callocobject()
-    cres = callocobject()
-
-    _op_integer(n, cn)
-
-    chartafel(cn, cres)
-
-    res = _py(cres)
-    
-    freeall(cn)
-    freeall(cres)
-
-    return res
-
-
-
-def charvalue_symmetrica(irred, cls, table=None):
-    """
-    you enter a PARTITION object part, labelling the irreducible
-    character, you enter a PARTITION object class, labeling the class
-    or class may be a PERMUTATION object, then result becomes the value
-    of that character on that class or permutation. Note that the
-    table may be NULL, in which case the value is computed, or it may be 
-    taken from a precalculated charactertable.
-    FIXME: add table paramter
-
-    EXAMPLES:
-        sage: n = 3
-        sage: m = matrix([[symmetrica.charvalue(irred, cls) for cls in Partitions(n)] for irred in Partitions(n)]); m
-        [ 1  1  1]
-        [-1  0  2]
-        [ 1 -1  1]
-        sage: m == symmetrica.chartafel(n)
-        True
-        sage: n = 4
-        sage: m = matrix([[symmetrica.charvalue(irred, cls) for cls in Partitions(n)] for irred in Partitions(n)])
-        sage: m == symmetrica.chartafel(n)
-        True
-    """
-
-    cdef OP cirred, cclass, ctable, cresult
-
-    
-    cirred = callocobject()
-    cclass = callocobject()
-    cresult = callocobject()
-
-    if table == None:
-        ctable = NULL
-    else:
-        ctable = callocobject()
-        _op_matrix(table, ctable)
-
-
-
-    #FIXME: assume that class is a partition
-    _op_partition(cls, cclass)
-
-    _op_partition(irred, cirred)
-
-    charvalue(cirred, cclass, cresult, ctable)
-
-    res = _py(cresult)
-
-    freeall(cirred)
-    freeall(cclass)
-    freeall(cresult)
-    if ctable != NULL:
-        freeall(ctable)
-
-    return res
-
-
-
-def kranztafel_symmetrica(a, b):
-    """
-    you enter the INTEGER objects, say a and b, and res becomes a
-    MATRIX object, the charactertable of S_b \wr S_a, co becomes a
-    VECTOR object of classorders and cl becomes a VECTOR object of
-    the classlabels.
-
-    EXAMPLES:
-       sage: (a,b,c) = symmetrica.kranztafel(2,2)
-       sage: a
-       [ 1 -1  1 -1  1]
-       [ 1  1  1  1  1]
-       [-1  1  1 -1  1]
-       [ 0  0  2  0 -2]
-       [-1 -1  1  1  1]
-       sage: b
-       [2, 2, 1, 2, 1]
-       sage: for m in c: print m
-       ...
-       [0 0]
-       [0 1] 
-       [0 0]
-       [1 0] 
-       [0 2]
-       [0 0] 
-       [1 1]
-       [0 0] 
-       [2 0]
-       [0 0] 
-
-    """
-    
-    cdef OP ca, cb, cres, cco, ccl
-
-    
-    ca = callocobject()
-    cb = callocobject()
-    cres = callocobject()
-    cco = callocobject()
-    ccl = callocobject()
-
-    _op_integer(a, ca)
-    _op_integer(b, cb)
-
-    kranztafel(ca,cb,cres,cco,ccl)
-
-    res = _py(cres)
-    co  = _py(cco)
-    cl  = _py(ccl)
-
-    freeall(ca)
-    freeall(cb)
-    freeall(cres)
-    freeall(cco)
-    freeall(ccl)
-
-    return (res, co, cl)
-    
-
-## def c_ijk_sn_symmetrica(i, j, k):
-##     """
-##     computes the coefficients of the class multiplication in the
-##     group algebra of the S_n. It uses the method described in
-##     Curtis/Reiner: Methods of representation theory I p. 216
-
-##     EXAMPLES:
-
-##     """
-
-##     cdef OP ci, cj, ck, cresult
-
-    
-##     ci = callocobject()
-##     cj = callocobject()
-##     cresult = callocobject()
-##     ck = callocobject()
-
-
-##     _op_partition(i, ci)
-##     _op_partition(j, cj)
-##     _op_partition(k, ck)
-
-##     c_ijk_sn(ci, cj, ck, cresult)
-
-##     res = _py(cresult)
-    
-##     freeall(ci)
-##     freeall(cj)
-##     freeall(cresult)
-##     freeall(ck)
-
-##     return res
-    
Index: age/libs/symmetrica/schur.pxi
===================================================================
--- sage/libs/symmetrica/schur.pxi	(revision 6437)
+++ 	(revision )
@@ -1,940 +1,0 @@
-cdef extern from 'symmetrica/def.h':
-    INT outerproduct_schur(OP parta, OP partb, OP result)
-    INT dimension_schur(OP a, OP result)
-    INT part_part_skewschur(OP big, OP small, OP result)
-    INT newtrans(OP perm, OP schur)
-    INT compute_schur_with_alphabet(OP part, OP length, OP poly)
-    INT compute_homsym_with_alphabet(OP number, OP length, OP poly)
-    INT compute_elmsym_with_alphabet(OP number, OP length, OP poly)
-    INT compute_monomial_with_alphabet(OP partition, OP length, OP poly)
-    INT compute_powsym_with_alphabet(OP number, OP length, OP poly)
-    INT compute_schur_with_alphabet_det(OP part, OP length, OP poly)
-
-    INT part_part_skewschur(OP a, OP b, OP c)
-
-    INT t_SCHUR_MONOMIAL(OP schur, OP result)
-    INT t_SCHUR_HOMSYM(OP a, OP b)
-    INT t_SCHUR_ELMSYM(OP a, OP b)
-
-    INT t_MONOMIAL_SCHUR(OP a, OP b)
-    INT t_MONOMIAL_HOMSYM(OP a, OP b)
-    INT t_MONOMIAL_ELMSYM(OP a, OP b)
-    
-    INT t_ELMSYM_SCHUR(OP a, OP b)
-    INT t_ELMSYM_MONOMIAL(OP a, OP b)
-    INT t_ELMSYM_HOMSYM(OP a, OP b)
-    
-    INT t_HOMSYM_SCHUR(OP a, OP b)
-    INT t_HOMSYM_MONOMIAL(OP a, OP b)
-    INT t_HOMSYM_ELMSYM(OP a, OP b)
-
-    
-    INT t_POWSYM_SCHUR(OP a, OP b)
-    INT t_SCHUR_POWSYM(OP a, OP b)
-    INT t_POWSYM_HOMSYM(OP a, OP b)
-    INT t_HOMSYM_POWSYM(OP a, OP b)
-    INT t_POWSYM_ELMSYM(OP a, OP b)
-    INT t_ELMSYM_POWSYM(OP a, OP b)
-    INT t_POWSYM_MONOMIAL(OP a, OP b)
-    INT t_MONOMIAL_POWSYM(OP a, OP b)
-
-    INT hall_littlewood(OP part, OP res)
-
-    INT mult_schur_schur(OP s1, OP s2, OP res)
-    INT mult_monomial_monomial(OP m1, OP m2, OP res)
-
-    INT t_POLYNOM_POWER(OP a, OP b)
-    INT t_POLYNOM_SCHUR(OP a, OP b)
-    INT t_POLYNOM_ELMSYM(OP a, OP b)
-    INT t_POLYNOM_MONOMIAL(OP a, OP b)
-    
-    INT symmetricp(OP a)
-
-    
-def outerproduct_schur_symmetrica(parta, partb):
-    """
-    you enter two PARTITION objects, and the result is
-    a SCHUR object, which is the expansion of the product
-    of the two schurfunctions, labbeled by
-    the two PARTITION objects parta and partb.
-    Of course this can also be interpreted as the decomposition of the 
-    outer tensor product of two irreducibe representations of the
-    symmetric group.
-    """
-    cdef OP cparta, cpartb, cresult
-
-    cparta  = callocobject()
-    cpartb  = callocobject()
-    cresult = callocobject()
-    
-    _op_partition(parta, cparta)
-    _op_partition(partb, cpartb)
-
-    _sig_on
-    outerproduct_schur(cparta, cpartb, cresult)
-    _sig_off
-    
-    res = _py(cresult)
-
-    freeall(cparta)
-    freeall(cpartb)
-    freeall(cresult)
-
-    return res
-
-
-def dimension_schur_symmetrica(s):
-    """
-    you enter a SCHUR object a, and the result is the
-    dimension of the corresponding representation of the
-    symmetric group sn.
-    """
-    cdef OP ca, cresult
-
-    cresult = callocobject()
-    ca      = callocobject()
-
-    _op_schur(s, ca)
-    _sig_on
-    dimension_schur(ca, cresult)
-    _sig_off
-    res = _py(cresult)
-
-    freeall(ca)
-    freeall(cresult)
-
-    return res
-
-
-def part_part_skewschur_symmetrica(big, small):
-    """
-    you enter two PARTITION objects big and small, where big is
-    a partition which contains small, and result becomes a SCHUR
-    object, which represents the decomposition of the corresponding
-    skew partition.
-
-    """
-
-    cdef OP cbig, csmall, cresult
-
-    cbig = callocobject()
-    csmall = callocobject()
-    cresult = callocobject()
-
-    _op_partition(big, cbig)
-    _op_partition(small, csmall)
-    _sig_on
-    part_part_skewschur(cbig, csmall, cresult)
-    _sig_off
-    res = _py(cresult)
-
-    freeall(cbig)
-    freeall(csmall)
-    freeall(cresult)
-
-    return res
-
-
-
-def newtrans_symmetrica(perm):
-    """
-    computes the decomposition of a schubertpolynomial labeled by 
-    the permutation perm, as a sum of Schurfunction.
-    FIXME!
-    """
-    cdef OP cperm = callocobject(), cresult = callocobject()
-
-    _op_permutation(perm, cperm)
-
-    _sig_on
-    newtrans(cperm, cresult)
-    _sig_off
-    
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cperm)
-
-    return res
-
-
-def compute_schur_with_alphabet_symmetrica(part, length, alphabet='x'):
-    """
-    computes the expansion of a schurfunction labeled by a
-    partition PART as a POLYNOM erg. The INTEGER length specifies the
-    length of the alphabet.
-    """
-    late_import()
-    cdef OP cpart = callocobject(), cresult = callocobject(), clength = callocobject()
-
-    _op_partition(part, cpart)
-    _op_integer(length, clength)
-
-    _sig_on
-    compute_schur_with_alphabet(cpart, clength, cresult)
-    _sig_off
-    
-    res = _py_polynom_alphabet(cresult, alphabet)
-    
-    freeall(cresult)
-    freeall(cpart)
-
-    return res
-    
-
-def compute_homsym_with_alphabet_symmetrica(n, length, alphabet='x'):
-    """
-    computes the expansion of a homogenous(=complete) symmetric 
-    function labeled by a INTEGER number as a POLYNOM erg.
-    The object number may also be a  PARTITION or a HOM_SYM object.
-    The INTEGER laenge specifies the length of the alphabet.
-    Both routines are the same.
-    """
-    late_import()
-    cdef OP cn = callocobject(), clength = callocobject(), cresult = callocobject()
-
-    if isinstance(n, (int, Integer)):
-        _op_integer(n, cn)
-    elif isinstance(n, (builtinlist, Partition_class)):
-        _op_partition(n, cn)
-    else:
-        raise NotImplementedError, "need to write code for HOM_SYM"        
-
-    _op_integer(length, clength)
-
-    _sig_on
-    compute_homsym_with_alphabet(cn, clength, cresult)
-    _sig_off
-    
-    res = _py_polynom_alphabet(cresult, alphabet)
-
-    freeall(cresult)
-    freeall(cn)
-    freeall(clength)
-
-    return res
-
-
-def compute_elmsym_with_alphabet_symmetrica(n, length, alphabet='x'):
-    """
-    computes the expansion of a elementary symmetric 
-    function labeled by a INTEGER number as a POLYNOM erg.
-    The object number may also be a  PARTITION or a ELM_SYM object.
-    The INTEGER laenge specifies the length of the alphabet.
-    Both routines are the same.
-    """
-    late_import()
-    cdef OP cn = callocobject(), clength = callocobject(), cresult = callocobject()
-
-    if isinstance(n, (int, Integer)):
-        _op_integer(n, cn)
-    elif isinstance(n, (builtinlist, Partition_class)):
-        _op_partition(n, cn)
-    else:
-        raise NotImplementedError, "need to write code for ELM_SYM"        
-
-    _op_integer(length, clength)
-
-    _sig_on
-    compute_elmsym_with_alphabet(cn, clength, cresult)
-    _sig_off
-    
-    res = _py_polynom_alphabet(cresult, alphabet)
-
-    freeall(cresult)
-    freeall(cn)
-    freeall(clength)
-
-    return res
-
-
-def compute_monomial_with_alphabet_symmetrica(n, length, alphabet='x'):
-    """
-    computes the expansion of a monomial symmetric 
-    function labeled by a PARTITION number as a POLYNOM erg.
-    The INTEGER laenge specifies the length of the alphabet.
-
-    """
-    late_import()
-    cdef OP cn = callocobject(), clength = callocobject(), cresult = callocobject()
-
-    _op_partition(n, cn)
-    _op_integer(length, clength)
-
-    _sig_on
-    compute_monomial_with_alphabet(cn, clength, cresult)
-    _sig_off
-    
-    res = _py_polynom_alphabet(cresult, alphabet)
-
-    freeall(cresult)
-    freeall(cn)
-    freeall(clength)
-
-    return res
-
-
-def compute_powsym_with_alphabet_symmetrica(n, length, alphabet='x'):
-    """
-    computes the expansion of a power symmetric 
-    function labeled by a INTEGER label or by a PARTITION label
-    or a POW_SYM label as a POLYNOM erg.
-    The INTEGER laenge specifies the length of the alphabet.
-    """
-    late_import()
-    cdef OP cn = callocobject(), clength = callocobject(), cresult = callocobject()
-
-    if isinstance(n, (int, Integer)):
-        _op_integer(n, cn)
-    elif isinstance(n, (builtinlist, Partition_class)):
-        _op_partition(n, cn)
-    else:
-        raise NotImplementedError, "need to write code for POW_SYM"        
-
-    _op_integer(length, clength)
-
-    _sig_on
-    compute_powsym_with_alphabet(cn, clength, cresult)
-    _sig_off
-    
-    res = _py_polynom_alphabet(cresult, alphabet)
-
-    freeall(cresult)
-    freeall(cn)
-    freeall(clength)
-
-    return res
-
-
-def compute_schur_with_alphabet_det_symmetrica(part, length, alphabet='x'):
-    """
-    computes the expansion of a skewschurfunction labeled by the
-    SKEWPARTITION skewpart, using the Jacobi Trudi Identity, 
-    the result is the
-    POLYNOM erg, the length of the alphabet is given by INTEGER length.
-    
-    """
-    cdef OP cpart = callocobject(), cresult = callocobject(), clength = callocobject()
-
-    _op_partition(part, cpart)
-    _op_integer(length, clength)
-
-    _sig_on
-    compute_schur_with_alphabet_det(cpart, clength, cresult)
-    _sig_off
-    
-    res = _py_polynom_alphabet(cresult, alphabet)
-
-    freeall(cresult)
-    freeall(cpart)
-    freeall(clength)
-
-    return res
-
-def part_part_skewschur_symmetric(outer, inner):
-    """
-    Returns the skew schur function s_{outer/inner}
-
-    EXAMPLES:
-        sage: symmetrica.part_part_skewschur([3,2,1],[2,1])
-        s[1, 1, 1] + 2*s[2, 1] + s[3]
-    """
-    cdef OP couter = callocobject(), cinner = callocobject(), cresult = callocobject()
-
-    _op_partition(outer, couter)
-    _op_partition(inner, cinner)
-
-    _sig_on
-    part_part_skewschur(couter, cinner, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(couter)
-    freeall(cinner)
-    freeall(cresult)
-
-    return res
-
-def hall_littlewood_symmetrica(part):
-    """
-    computes the so called Hall Littlewood Polynomials, i.e.
-    a SCHUR object, whose coefficient are polynomials in one
-    variable. The method, which is used for the computation is described
-    in the paper: A.O. Morris The Characters of the group GL(n,q)
-    Math Zeitschr 81, 112-123 (1963)
-    """
-
-    cdef OP cpart = callocobject(), cresult = callocobject()
-
-    _op_partition(part, cpart)
-
-    _sig_on
-    hall_littlewood(cpart, cresult)
-    _sig_off
-    
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cpart)
-
-    return res
-
-
-def t_SCHUR_MONOMIAL_symmetrica(schur):
-    """
-    """
-
-    cdef OP cschur = callocobject(), cresult = callocobject()
-
-    _op_schur(schur, cschur)
-
-    _sig_on
-    t_SCHUR_MONOMIAL(cschur, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cschur)
-
-    return res
-      
-
-
-def t_SCHUR_HOMSYM_symmetrica(schur):
-    """
-    """
-
-    cdef OP cschur = callocobject(), cresult = callocobject()
-
-    _op_schur(schur, cschur)
-
-    _sig_on
-    t_SCHUR_HOMSYM(cschur, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cschur)
-
-    return res
-
-
-def t_SCHUR_ELMSYM_symmetrica(schur):
-    """
-    """
-
-    cdef OP cschur = callocobject(), cresult = callocobject()
-
-    _op_schur(schur, cschur)
-
-    _sig_on
-    t_SCHUR_ELMSYM(cschur, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cschur)
-
-    return res
-
-
-def t_SCHUR_POWSYM_symmetrica(schur):
-    """
-    
-    """
-
-    cdef OP cschur = callocobject(), cresult = callocobject()
-
-    _op_schur(schur, cschur)
-
-    _sig_on
-    t_SCHUR_POWSYM(cschur, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cschur)
-
-    return res
-
-def t_POLYNOM_SCHUR_symmetrica(p):
-    """
-    Converts a symmetric polynomial with base ring QQ or ZZ into a symmetric function
-    in the Schur basis.
-    """
-    cdef OP polynom = callocobject(), cresult = callocobject()
-
-    _op_polynom(p, polynom)
-
-    if not symmetricp(polynom):
-        raise ValueError, "the polynomial must be symmetric"
-
-    _sig_on
-    t_POLYNOM_SCHUR(polynom, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(polynom)
-
-    return res
-
-
-
-
-
-def t_MONOMIAL_HOMSYM_symmetrica(monomial):
-    """
-    
-    """
-
-    cdef OP cmonomial = callocobject(), cresult = callocobject()
-
-    _op_monomial(monomial, cmonomial)
-
-    _sig_on
-    t_MONOMIAL_HOMSYM(cmonomial, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cmonomial)
-
-    return res
-
-def t_MONOMIAL_ELMSYM_symmetrica(monomial):
-    """
-    
-    """
-
-    cdef OP cmonomial = callocobject(), cresult = callocobject()
-
-    _op_monomial(monomial, cmonomial)
-
-    _sig_on
-    t_MONOMIAL_ELMSYM(cmonomial, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cmonomial)
-
-    return res
-
-
-def t_MONOMIAL_SCHUR_symmetrica(monomial):
-    """
-    
-    """
-
-    cdef OP cmonomial = callocobject(), cresult = callocobject()
-
-    _op_monomial(monomial, cmonomial)
-
-    _sig_on
-    t_MONOMIAL_SCHUR(cmonomial, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cmonomial)
-
-    return res
-            
-
-def t_MONOMIAL_POWSYM_symmetrica(monomial):
-    """
-    
-    """
-
-    cdef OP cmonomial = callocobject(), cresult = callocobject()
-
-    _op_monomial(monomial, cmonomial)
-
-    _sig_on
-    t_MONOMIAL_POWSYM(cmonomial, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cmonomial)
-
-    return res
-
-def t_POLYNOM_MONOMIAL_symmetrica(p):
-    """
-    Converts a symmetric polynomial with base ring QQ or ZZ into a symmetric function
-    in the monomial basis.
-    """
-    cdef OP polynom = callocobject(), cresult = callocobject()
-
-    _op_polynom(p, polynom)
-
-    if not symmetricp(polynom):
-        raise ValueError, "the polynomial must be symmetric"
-
-    _sig_on
-    t_POLYNOM_MONOMIAL(polynom, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(polynom)
-
-    return res
-
-
-def t_ELMSYM_SCHUR_symmetrica(elmsym):
-    """
-    
-    """
-
-    cdef OP celmsym = callocobject(), cresult = callocobject()
-
-    _op_elmsym(elmsym, celmsym)
-
-    _sig_on
-    t_ELMSYM_SCHUR(celmsym, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(celmsym)
-
-    return res
-
-
-def t_ELMSYM_POWSYM_symmetrica(elmsym):
-    """
-    
-    """
-
-    cdef OP celmsym = callocobject(), cresult = callocobject()
-
-    _op_elmsym(elmsym, celmsym)
-
-    _sig_on
-    t_ELMSYM_POWSYM(celmsym, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(celmsym)
-
-    return res
-
-def t_ELMSYM_MONOMIAL_symmetrica(elmsym):
-    """
-    
-    """
-
-    cdef OP celmsym = callocobject(), cresult = callocobject()
-
-    _op_elmsym(elmsym, celmsym)
-
-    _sig_on
-    t_ELMSYM_MONOMIAL(celmsym, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(celmsym)
-
-    return res
-
-
-
-def t_ELMSYM_HOMSYM_symmetrica(elmsym):
-    """
-    
-    """
-
-    cdef OP celmsym = callocobject(), cresult = callocobject()
-
-    _op_elmsym(elmsym, celmsym)
-
-    _sig_on
-    t_ELMSYM_HOMSYM(celmsym, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(celmsym)
-
-    return res
-
-def t_POLYNOM_ELMSYM_symmetrica(p):
-    """
-    Converts a symmetric polynomial with base ring QQ or ZZ into a symmetric function
-    in the elementary basis.
-    """
-    cdef OP polynom = callocobject(), cresult = callocobject()
-
-    _op_polynom(p, polynom)
-
-    if not symmetricp(polynom):
-        raise ValueError, "the polynomial must be symmetric"
-
-    _sig_on
-    t_POLYNOM_ELMSYM(polynom, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(polynom)
-
-    return res
-
-
-
-def t_HOMSYM_SCHUR_symmetrica(homsym):
-    """
-    
-    """
-
-    cdef OP chomsym = callocobject(), cresult = callocobject()
-
-    _op_homsym(homsym, chomsym)
-
-    _sig_on
-    t_HOMSYM_SCHUR(chomsym, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(chomsym)
-
-    return res
-
-def t_HOMSYM_POWSYM_symmetrica(homsym):
-    """
-    
-    """
-
-    cdef OP chomsym = callocobject(), cresult = callocobject()
-
-    _op_homsym(homsym, chomsym)
-
-    _sig_on
-    t_HOMSYM_POWSYM(chomsym, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(chomsym)
-
-    return res
-
-
-
-
-def t_HOMSYM_MONOMIAL_symmetrica(homsym):
-    """
-    
-    """
-
-    cdef OP chomsym = callocobject(), cresult = callocobject()
-
-    _op_homsym(homsym, chomsym)
-
-    _sig_on
-    t_HOMSYM_MONOMIAL(chomsym, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(chomsym)
-
-    return res
-
-def t_HOMSYM_ELMSYM_symmetrica(homsym):
-    """
-    
-    """
-
-    cdef OP chomsym = callocobject(), cresult = callocobject()
-
-    _op_homsym(homsym, chomsym)
-
-    _sig_on
-    t_HOMSYM_ELMSYM(chomsym, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(chomsym)
-
-    return res
-
-
-
-def t_POWSYM_MONOMIAL_symmetrica(powsym):
-    """
-    
-    """
-
-    cdef OP cpowsym = callocobject(), cresult = callocobject()
-
-    _op_powsym(powsym, cpowsym)
-
-    _sig_on
-    t_POWSYM_MONOMIAL(cpowsym, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cpowsym)
-
-    return res
-
-
-
-
-def t_POWSYM_SCHUR_symmetrica(powsym):
-    """
-    
-    """
-
-    cdef OP cpowsym = callocobject(), cresult = callocobject()
-
-    _op_powsym(powsym, cpowsym)
-
-    _sig_on
-    t_POWSYM_SCHUR(cpowsym, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cpowsym)
-
-    return res
-
-def t_POWSYM_ELMSYM_symmetrica(powsym):
-    """
-    
-    """
-
-    cdef OP cpowsym = callocobject(), cresult = callocobject()
-
-    _op_powsym(powsym, cpowsym)
-
-    _sig_on
-    t_POWSYM_ELMSYM(cpowsym, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cpowsym)
-
-    return res
-
-def t_POWSYM_HOMSYM_symmetrica(powsym):
-    """
-    
-    """
-
-    cdef OP cpowsym = callocobject(), cresult = callocobject()
-
-    _op_powsym(powsym, cpowsym)
-
-    _sig_on
-    t_POWSYM_HOMSYM(cpowsym, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(cpowsym)
-
-    return res
-
-def t_POLYNOM_POWER_symmetrica(p):
-    """
-    Converts a symmetric polynomial with base ring QQ or ZZ into a symmetric function
-    in the power sum basis.
-    """
-    cdef OP polynom = callocobject(), cresult = callocobject()
-
-    _op_polynom(p, polynom)
-
-    if not symmetricp(polynom):
-        raise ValueError, "the polynomial must be symmetric"
-
-    _sig_on
-    t_POLYNOM_POWER(polynom, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cresult)
-    freeall(polynom)
-
-    return res
-
-
-def mult_schur_schur_symmetrica(s1, s2):
-    """
-    """
-    cdef OP cs1 = callocobject(), cs2 = callocobject(), cresult = callocobject()
-
-    _op_schur(s1, cs1)
-    _op_schur(s2, cs2)
-
-    _sig_on
-    mult_schur_schur(cs1, cs2, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cs1)
-    freeall(cs2)
-    freeall(cresult)
-
-    return res
-
-
-
-def mult_monomial_monomial_symmetrica(m1, m2):
-    """
-    """
-    cdef OP cm1 = callocobject(), cm2 = callocobject(), cresult = callocobject()
-
-    _op_monomial(m1, cm1)
-    _op_monomial(m2, cm2)
-
-    _sig_on
-    mult_monomial_monomial(cm1, cm2, cresult)
-    _sig_off
-
-    res = _py(cresult)
-
-    freeall(cm1)
-    freeall(cm2)
-    freeall(cresult)
-
-    return res
-
-
Index: age/libs/symmetrica/symmetrica.pxi
===================================================================
--- sage/libs/symmetrica/symmetrica.pxi	(revision 6437)
+++ 	(revision )
@@ -1,1064 +1,0 @@
-cdef extern from "Python.h":
-    object PyString_FromStringAndSize(char *s, int len)
-    int PyObject_TypeCheck(object o, object type)
-
-cdef extern from 'symmetrica/macro.h':
-    pass
-
-cdef extern from 'symmetrica/def.h':
-    ctypedef int INT
-    ctypedef INT OBJECTKIND
-
-    ctypedef struct vector:
-        pass
-    ctypedef struct bruch:
-        pass
-    ctypedef struct graph:
-        pass
-    ctypedef struct list:
-        pass
-    ctypedef struct longint:
-        pass
-    ctypedef struct matrix:
-        pass
-    ctypedef struct monom:
-        pass
-    ctypedef struct number:
-        pass
-    ctypedef struct partition: 
-        pass
-    ctypedef struct permutation:
-        pass
-    ctypedef struct reihe:
-        pass
-    ctypedef struct skewpartition:
-        pass
-    ctypedef struct symchar:
-        pass
-    ctypedef struct tableaux:
-        pass
-    
-    ctypedef union OBJECTSELF:
-        INT ob_INT
-        INT *ob_INTpointer
-        char *ob_charpointer
-        bruch *ob_bruch
-        graph *ob_graph
-        list *ob_list
-        longint *ob_longint
-        matrix *ob_matrix
-        monom *ob_monom
-        number *ob_number
-        partition *ob_partition
-        permutation *ob_permutation
-        reihe *ob_reihe
-        skewpartition *ob_skewpartition
-        symchar *ob_symchar
-        tableaux *ob_tableaux
-        vector *ob_vector
-      
-    
-    cdef enum:
-        INFREELIST = -1
-        EMPTY = 0
-        INTEGER = 1
-        VECTOR = 2
-        PARTITION = 3
-        FRACTION = 4
-        BRUCH = 4
-        PERMUTATION = 6
-        SKEWPARTITION = 7
-        TABLEAUX = 8
-        POLYNOM = 9
-        SCHUR = 10
-        MATRIX = 11
-        AUG_PART = 12
-        HOM_SYM = 13
-        HOMSYM = 13
-        SCHUBERT = 14
-        INTEGERVECTOR = 15
-        INEGER_VECTOR = 15
-        INT_VECTOR = 15
-        INTVECTOR = 15
-        KOSTKA = 16
-        INTINT = 17
-        SYMCHAR = 18
-        WORD =19
-        LIST =20 # 210688 */
-        MONOM =21 #230688*/
-        LONGINT =22 # 170888 */
-        GEN_CHAR =23 # 280888  nur fuer test-zwecke */
-        BINTREE =24 # 291288 */
-        GRAPH =25 # 210889 */
-        COMP =26 # 300889 */
-        COMPOSITION =26 # 300889 */
-        KRANZTYPUS =27 # 280390 */
-        POW_SYM =28
-        POWSYM =28
-        MONOMIAL =29  # 090992 */
-        BTREE =30
-        KRANZ =31
-        GRAL =32 # 200691 */
-        GROUPALGEBRA =32 # 170693 */
-        ELM_SYM =33  # 090992 */
-        ELMSYM =33  # 090992 */
-        FINITEFIELD = 35 # 250193 */
-        FF = 35 # 250193 */
-        REIHE = 36 # 090393 */
-        CHARPARTITION = 37 # 130593 */ # internal use */
-        CHAR_AUG_PART = 38 # 170593 */ # internal use */
-        INTEGERMATRIX =40 # AK 141293 */
-        CYCLOTOMIC = 41 # MD */
-        CYCLOTOMIC = 41 # MD */
-        MONOPOLY = 42 # MD */
-        SQ_RADICAL = 43 # MD */
-        BITVECTOR = 44 
-        LAURENT =45
-        SUBSET =47 # AK 220997 */
-        FASTPOLYNOM =211093
-        EXPONENTPARTITION =240298
-        SKEWTABLEAUX =20398
-        PARTTABLEAUX =10398
-        BARPERM =230695
-        PERMVECTOR =180998
-        PERM_VECTOR =180998
-        PERMUTATIONVECTOR =180998
-        PERMUTATION_VECTOR =180998
-        INTEGERBRUCH =220998
-        INTEGER_BRUCH =220998
-        INTEGERFRACTION =220998
-        INTEGER_FRACTION =220998
-        HASHTABLE  =120199
-
-        
- 
-    ctypedef struct loc:
-        INT w2, w1, w0
-        loc *nloc
-
-    ctypedef struct longint:
-        loc *floc
-        signed char signum #-1,0,+1
-        INT laenge
-
-    
-
-    ctypedef struct ganzdaten:
-        INT basis, basislaenge, auspos, auslaenge, auszz
-
-    ctypedef struct zahldaten:
-        char ziffer[13]
-        INT mehr
-        INT ziffernzhal
-        loc *fdez
-    
-
-    ctypedef struct obj:
-        OBJECTKIND ob_kind
-        OBJECTSELF ob_self
-        
-    ctypedef obj *OP
-
-    ctypedef struct vector:
-        OP v_length
-        OP v_self
-
-    ctypedef struct REIHE_variablen:
-        INT index
-        INT potenz
-        REIHE_variablen *weiter
-
-    ctypedef struct REIHE_mon:
-        OP coeff
-        REIHE_variablen *zeiger
-        REIHE_mon *ref
-
-    ctypedef struct REIHE_poly:
-        INT grad
-        REIHE_mon *uten
-        REIHE_poly *rechts
-
-    ctypedef struct reihe:
-        INT exist
-        INT reihenart
-        INT z
-        reihe *x, *y
-        reihe *p
-        INT (*eingabefkt)()
-        char ope
-        REIHE_poly *infozeig
-
-    ctypedef reihe* REIHE_ZEIGER
-
-    ctypedef struct list:
-        OP l_self
-        OP l_next
-
-    ctypedef struct partition:
-        OBJECTKIND pa_kind
-        OP pa_self
-
-    ctypedef struct permutation:
-        OBJECTKIND p_kind
-        OP p_self
-
-    ctypedef struct monom:
-        OP mo_self
-        OP mo_koeff
-
-    ctypedef struct bruch:
-        OP b_oben
-        OP b_uten
-        INT b_info
-
-    ctypedef struct matrix:
-        OP m_length
-        OP m_height
-        OP m_self
-
-    ctypedef struct skewpartition:
-        OP spa_gross
-        OP spa_klein
-
-    ctypedef struct tableaux:
-        OP t_umriss
-        OP t_self
-
-    ctypedef struct symchar:
-        OP sy_werte
-        OP sy_parlist
-        OP sy_dimension
-
-    ctypedef struct graph:
-        OBJECTKIND gr_kind
-        OP gr_self
-
-    ctypedef struct CYCLO_DATA:
-        OP index, deg, poly, autos
-
-    ctypedef struct FIELD_DATA:
-        OP index, deg, poly
-
-    ctypedef union data:
-        CYCLO_DATA *c_data
-        FIELD_DATA *f_data
-        OP o_data
-
-    ctypedef struct number:
-        OP n_self
-        data n_data
-
-
-    #MACROS
-    #S_PA_I(OP a, INT i)
-    OBJECTKIND s_o_k(OP a)
-    void* c_o_k(OP a, OBJECTKIND k)
-
-
-    void* println(OP a)
-    
-    #Integers
-    void* m_i_i(INT n, OP a)
-    void* M_I_I(INT n, OP a)
-    INT S_I_I(OP a)
-
-    #Fractions
-    OP S_B_O(OP a)
-    OP S_B_U(OP a)
-    OP m_ou_b(OP o, OP u, OP d)
-
-    #Vectors
-    void* M_IL_V(INT length, OP a)
-    void* m_il_v(INT n, OP a )
-    void* m_i_i(INT n, OP a)
-    
-    INT s_v_li(OP a)
-    OP s_v_i(OP a, INT i)
-
-    #Partitions
-    OP s_pa_l(OP a)
-    INT s_pa_li(OP a)
-    INT s_pa_ii(OP a, INT i)
-    OP s_pa_i(OP a, INT i)
-    OP S_PA_S(OP a)
-    OP S_PA_I(OP a, INT )
-    void* b_ks_pa(INT kind, OP b, OP a)   
-
-
-    #Skew Partitions
-    INT b_gk_spa(OP gross, OP klein, OP result)
-    INT m_gk_spa(OP gross, OP klein, OP result)    
-    OP s_spa_g(OP spa)
-    OP s_spa_k(OP spa)
-
-    #Permutations
-    OP s_p_i(OP a, INT i)
-    INT s_p_li(OP a)
-    INT s_p_ii(OP a, INT i)
-    void* m_il_p(INT n, OP a)
-
-
-    #Barred Permutations
-
-
-    #Lists
-    OP s_l_s(OP a)
-    OP S_L_S(OP a)
-    OP s_l_n(OP a)
-    INT lastp_list(OP l)
-    INT empty_listp(OP l)
-
-    #Matrices
-    INT S_M_HI(OP a)
-    INT S_M_LI(OP a)
-    OP S_M_IJ(OP a, INT i, INT j)
-    void* m_ilih_m(INT l, INT h, OP a)
-
-    #Schur polynomials
-    OP s_s_s(OP a)
-    OP s_s_k(OP a)
-    OP s_s_n(OP a)
-    void* m_skn_s(OP part, OP koeff, OP next, OP result)
-    void* b_skn_s(OP part, OP koeff, OP next, OP result)
-
-    #Schubert polynomials
-    OP s_sch_s(OP a)
-    OP s_sch_k(OP a)
-    OP s_sch_n(OP a)
-    void* m_skn_sch(OP perm, OP koeff, OP next, OP result)
-    void* b_skn_sch(OP perm, OP koeff, OP next, OP result)    
-    
-    #Polynomials
-    OP s_po_n(OP a)
-    OP s_po_sl(OP a)
-    OP s_po_k(OP a)
-    OP s_po_s(OP a)
-    void* m_skn_po(OP s, OP k, OP next, OP polynom)
-    
-    #Tableaux
-    OP S_T_S(OP t)
-
-    #########
-
-    INT insert(OP a, OP b, INT (*eq)(), INT (*comp)())
-
-
-    INT nullp_sqrad(OP a)
-    OP S_PO_K(OP a)
-    OP S_PO_S(OP a)
-    OP S_L_N(OP a)
-    OP S_N_S(OP a)
-    INT einsp(OP A)
-
-    #Empty Object
-    int EMPTYP(OP obj)
-    
-    #Functions
-    INT anfang()
-    INT ende()
-    OP callocobject()
-    INT sscan(INT, OP a)
-    INT scan(INT, OP a)
-    INT freeall(OP a)
-    INT freeself(OP a)
-    INT sprint(char* t, OP a)
-    INT sprint_integer(char* t, OP A)
-    INT println(OP a)
-
-    #factorial
-    INT fakul(OP a, OP b)
-
-##########################################
-cdef object matrix_constructor
-cdef object Integer
-cdef object Tableau
-cdef object SkewPartition, SkewPartition_class
-cdef object Partition, Partition_class
-cdef object Permutation_class
-cdef object builtinlist
-cdef object sqrt
-cdef object Rational
-cdef object QQ
-cdef object ZZ
-cdef object SymmetricFunctionAlgebra
-cdef object PolynomialRing
-cdef object SchubertPolynomialRing
-
-cdef void late_import():
-    global matrix_constructor, \
-           Integer, \
-           Tableau, \
-           SkewPartition, \
-           SkewPartition_class, \
-           Partition, \
-           Partition_class, \
-           Permutation_class, \
-           prod, \
-           PolynomialRing, \
-           Rational, \
-           QQ, \
-           ZZ, \
-           SymmetricFunctionAlgebra, \
-           sqrt, \
-           builtinlist, \
-           MPolynomialRing_generic, \
-           SchubertPolynomialRing
-
-    if matrix_constructor is not None:
-        return
-
-    import sage.matrix.constructor
-    matrix_constructor = sage.matrix.constructor.matrix
-
-    import sage.rings.integer
-    Integer = sage.rings.integer.Integer
-
-    import sage.combinat.tableau
-    Tableau = sage.combinat.tableau.Tableau
-
-    import sage.combinat.skew_partition
-    SkewPartition = sage.combinat.skew_partition.SkewPartition
-    SkewPartition_class = sage.combinat.skew_partition.SkewPartition_class
-
-    import sage.combinat.partition
-    Partition = sage.combinat.partition.Partition
-    Partition_class = sage.combinat.partition.Partition_class
-
-    import sage.combinat.permutation
-    Permutation_class = sage.combinat.permutation.Permutation_class
-    
-    import sage.calculus.calculus
-    sqrt = sage.calculus.calculus.Function_sqrt()
-
-    import sage.misc.misc
-    prod = sage.misc.misc.prod
-
-    import sage.rings.polynomial.polynomial_ring_constructor
-    PolynomialRing =  sage.rings.polynomial.polynomial_ring_constructor.PolynomialRing
-
-    import sage.rings.rational
-    Rational = sage.rings.rational.Rational
-
-    import sage.rings.rational_field
-    QQ = sage.rings.rational_field.RationalField()
-
-    import sage.rings.integer_ring
-    ZZ = sage.rings.integer_ring.IntegerRing()
-    
-    #Symmetric Function Algebra
-    import sage.combinat.sfa
-    SymmetricFunctionAlgebra = sage.combinat.sfa.SymmetricFunctionAlgebra
-    
-    import __builtin__
-    builtinlist = __builtin__.list
-
-    import sage.rings.polynomial.multi_polynomial_ring
-    MPolynomialRing_generic = sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_generic
-
-    import sage.combinat.schubert_polynomial
-    SchubertPolynomialRing = sage.combinat.schubert_polynomial.SchubertPolynomialRing
-
-##########################################
-cdef object _py(OP a):
-    cdef OBJECTKIND objk
-    objk = s_o_k(a)
-    #print objk
-    if objk == INTEGER:
-        return _py_integer(a)
-    elif objk == PARTITION:
-        return _py_partition(a)
-    elif objk == PERMUTATION:
-        return _py_permutation(a)
-    elif objk == SKEWPARTITION:
-        return _py_skew_partition(a)
-    elif objk == FRACTION:
-        return _py_fraction(a)
-    elif objk == SQ_RADICAL:
-        return _py_sq_radical(a)
-    elif objk == MATRIX or objk == KRANZTYPUS:
-        return _py_matrix(a)
-    elif objk == SCHUR:
-        return _py_schur(a)
-    elif objk == HOMSYM:
-        return _py_homsym(a)
-    elif objk == POWSYM:
-        return _py_powsym(a)
-    elif objk == ELMSYM:
-        return _py_elmsym(a)
-    elif objk == MONOMIAL:
-        return _py_monomial(a)
-    elif objk == LIST:
-        return _py_list(a)
-    elif objk == VECTOR:
-        return _py_vector(a)
-    elif objk == TABLEAUX:
-        return _py_tableau(a)
-    elif objk == EMPTY:
-        return None
-    elif objk == POLYNOM:
-        return _py_polynom(a)
-    elif objk == SCHUBERT:
-        return _py_schubert(a)
-    else:
-        #println(a)
-        raise NotImplementedError, str(objk)
-
-cdef void* _op(object a, OP result):
-    late_import()
-    if isinstance(a, Integer):
-        _op_integer(a, result)
-    elif isinstance(a, Partition_class):
-        _op_partition(a, result)
-    elif isinstance(a, Rational):
-        _op_fraction(a, result)
-    else:
-        raise TypeError, "cannot convert a (= %s) to OP"%a
-
-##########
-#Integers#
-##########
-cdef void* _op_integer(object x, OP a):
-    #a.ob_kind = INTEGER
-    #a.ob_self = <OBJECTSELF>x
-    M_I_I(x, a)
-
-cdef object _py_integer(OP a):
-    late_import()
-    
-    return Integer(S_I_I(a))
-
-
-###########
-#Fractions#
-###########
-cdef object _py_fraction(OP a):
-    return _py_integer(S_B_O(a))/_py_integer(S_B_U(a))
-
-cdef void* _op_fraction(object f, OP a):
-    cdef OP o = callocobject(), u = callocobject()
-    _op_integer(f.numerator(), o)
-    _op_integer(f.denominator(), u)
-    m_ou_b(o, u, a)
-
-#########
-#Vectors#
-#########
-cdef object _py_vector(OP a):
-    cdef INT i
-    res = []
-    for i from 0 <= i < s_v_li(a):
-        res.append( _py(s_v_i(a, i)))
-    return res
-
-cdef void* _op_il_vector(object l, OP a):
-    cdef INT length, i
-    length = len(l)
-
-    m_il_v(length, a)
-    for i from 0 <= i < length:
-        m_i_i(l[i], s_v_i(a, i))
-        
-#########
-#Numbers#
-#########
-cdef object _py_sq_radical(OP a):
-    late_import()
-
-    cdef OP ptr
-    ptr = S_N_S(a)
-
-    res = 0
-    if nullp_sqrad(a):
-        return res
-
-    while ptr != NULL:
-
-        if einsp(S_PO_S(ptr)):
-            res += _py(S_PO_K(ptr))
-        else:
-            res += _py(S_PO_K(ptr))*sqrt(_py(S_PO_S(ptr)))
-            
-       
-        ptr = S_L_N(ptr);
-
-    return res.radical_simplify()
-
-############
-#Partitions#
-############
-cdef void* _op_partition(object p, OP a):
-    cdef int n, i, j
-
-    if not EMPTYP(a):
-        freeself(a)
-
-    n = len(p)
-    b_ks_pa(VECTOR, callocobject(), a)
-    m_il_v(n, S_PA_S(a))
-
-    j = 0
-    for i from n > i >= 0:
-        _op_integer(p[i], S_PA_I(a,j))
-        j = j + 1
-
-cdef object _py_partition(OP a):
-    cdef INT n, i
-    late_import()
-    res = []
-    n = s_pa_li(a)
-    for i from n > i >=0:
-        res.append(s_pa_ii(a, i))
-    return Partition(res)
-
-################
-#Skew Partition#
-################
-cdef void* _op_skew_partition(object p, OP a):
-    cdef OP gross, klein
-    gross = callocobject()
-    klein = callocobject()
-
-    #print p[0], p[1]
-    _op_partition(p[0], gross)
-    _op_partition(p[1], klein)
-   
-    b_gk_spa(gross, klein, a)
-
-cdef object _py_skew_partition(OP a):
-    late_import()
-    return SkewPartition( [ _py_partition(s_spa_g(a)), _py_partition(s_spa_k(a)) ] )
-
-##############
-#Permutations#
-##############
-cdef void* _op_permutation(object p, OP a):
-    cdef int n, i, j
-
-    if not EMPTYP(a):
-        freeself(a)
-
-    n = len(p)
-    m_il_p(n, a)
-    for i from 0 <= i < n:
-        _op_integer(p[i], s_p_i(a,i))
-        
-cdef object _py_permutation(OP a):
-    late_import()
-    cdef INT n, i
-    res = []
-    n = s_p_li(a)
-    for i from 0 <= i < n:
-        res.append(s_p_ii(a, i))
-    return Permutation_class(res)
-
-#####################
-#Barred Permutations#
-#####################
-
-#######
-#Lists#
-#######
-cdef object _py_list(OP a):
-    cdef OP x
-    x = a
-    res = []
-    if S_L_S(a) == NULL:
-        return []
-    elif empty_listp(a):
-        return []
-    while x  != NULL:
-        res.append(_py(s_l_s(x)))
-        x = s_l_n(x)
-
-    return res
-
-
-#############
-#Polynomials#
-#############
-cdef object _py_polynom(OP a):
-    late_import()
-    cdef int maxneeded = 0, i = 0
-    cdef OP pointer = a
-
-    if pointer == NULL:
-        return 0
-
-
-    #Find the maximum number of variables needed
-    while pointer != NULL:
-        l = _py(s_po_sl(pointer))
-        if l > maxneeded:
-            maxneeded = l
-        pointer = s_po_n(pointer)            
-
-    pointer = a
-    parent_ring = _py(s_po_k(pointer)).parent()
-    P = PolynomialRing(parent_ring, maxneeded, 'x')
-    x = P.gens()
-    res = P(0)
-    while pointer != NULL:
-        exps = _py_vector(s_po_s(pointer))
-        res += _py(s_po_k(pointer)) *prod([ x[i]**exps[i] for i in range(len(exps))])
-        pointer = s_po_n(pointer)
-    
-
-    return res
-
-cdef object _py_polynom_alphabet(OP a, object alphabet):
-    late_import()
-    cdef OP pointer = a
-
-    if pointer == NULL:
-        return 0
-    
-    l = _py(s_po_sl(a))
-    parent_ring = _py(s_po_k(pointer)).parent()
-    P = PolynomialRing(parent_ring, l, alphabet)
-    x = P.gens()
-    res = P(0)
-    while pointer != NULL:
-        exps = _py_vector(s_po_s(pointer))
-        res += _py(s_po_k(pointer)) *prod([ x[i]**exps[i] for i in range(len(exps))])
-        pointer = s_po_n(pointer)
-    return res
-
-cdef object _op_polynom(object d, OP res):
-    late_import()
-
-    poly_ring = d.parent()
-
-    if not PY_TYPE_CHECK(poly_ring, MPolynomialRing_generic):
-        raise TypeError, "you must pass a multivariate polynomial"
-    base_ring = poly_ring.base_ring()
-    
-    if not ( base_ring == ZZ or base_ring == QQ):
-        raise TypeError, "the base ring must be either ZZ or QQ"
-
-    cdef OP c = callocobject(), v = callocobject()
-    cdef OP pointer = res
-    m = d.monomials()
-    exp = d.exponents()
-    cdef int n, i
-    n = len(exp)
-    
-    for i from 0 <= i < n:
-        _op_il_vector(exp[i], v)
-        _op(d.monomial_coefficient(poly_ring(m[i])), c)
-        if i != n-1:
-            m_skn_po(v,c, callocobject(), pointer)
-        else:
-            m_skn_po(v,c, NULL, pointer)
-        pointer = s_po_n(pointer)
-    
-    freeall(c)
-    freeall(v)
-    return None
-    
-
-
-#######################################
-#Schur symmetric functions and friends#
-#######################################
-cdef object _py_schur(OP a):
-    late_import()
-    z_elt = _py_schur_general(a)
-    if len(z_elt) == 0:
-        return SymmetricFunctionAlgebra(ZZ, basis='s')(0)
-
-    #Figure out the parent ring of a coefficient
-    R = z_elt[ z_elt.keys()[0] ].parent()
-    
-    s = SymmetricFunctionAlgebra(R, basis='s')
-    z = s(0)
-    z._monomial_coefficients = z_elt
-    return z
-
-cdef void* _op_schur(object d, OP res):
-    _op_schur_general(d, res)
-
-cdef object _py_monomial(OP a): #Monomial symmetric functions
-    late_import()
-    z_elt = _py_schur_general(a)
-    if len(z_elt) == 0:
-        return SymmetricFunctionAlgebra(ZZ, basis='m')(0)
-
-    R = z_elt[ z_elt.keys()[0] ].parent()
-    
-    m = SymmetricFunctionAlgebra(R, basis='m')
-    z = m(0)
-    z._monomial_coefficients = z_elt
-    return z
-
-cdef void* _op_monomial(object d, OP res): #Monomial symmetric functions
-    cdef OP pointer = res
-    _op_schur_general(d, res)
-    while pointer != NULL:
-        c_o_k(pointer, MONOMIAL)
-        pointer = s_s_n(pointer)
-
-cdef object _py_powsym(OP a):  #Power-sum symmetric functions
-    late_import()
-    z_elt = _py_schur_general(a)
-    if len(z_elt) == 0:
-        return SymmetricFunctionAlgebra(ZZ, basis='p')(0)
-
-    R = z_elt[ z_elt.keys()[0] ].parent()
-    
-    p = SymmetricFunctionAlgebra(R, basis='p')
-    z = p(0)
-    z._monomial_coefficients = z_elt
-    return z
-
-cdef void* _op_powsym(object d, OP res): #Power-sum symmetric functions
-    cdef OP pointer = res
-    _op_schur_general(d, res)
-    while pointer != NULL:
-        c_o_k(pointer, POWSYM)
-        pointer = s_s_n(pointer)
-
-
-cdef object _py_elmsym(OP a): #Elementary symmetric functions
-    late_import()
-    z_elt = _py_schur_general(a)
-    if len(z_elt) == 0:
-        return SymmetricFunctionAlgebra(ZZ, basis='e')(0)
-
-    R = z_elt[ z_elt.keys()[0] ].parent()
-    
-    e = SymmetricFunctionAlgebra(R, basis='e')
-    z = e(0)
-    z._monomial_coefficients = z_elt
-    return z
-
-cdef void* _op_elmsym(object d, OP res): #Elementary symmetric functions
-    cdef OP pointer = res
-    _op_schur_general(d, res)
-    while pointer != NULL:
-        c_o_k(pointer, ELMSYM)
-        pointer = s_s_n(pointer)
-
-
-cdef object _py_homsym(OP a): #Homogenous symmetric functions
-    late_import()
-    z_elt = _py_schur_general(a)
-    if len(z_elt) == 0:
-        return SymmetricFunctionAlgebra(ZZ, basis='h')(0)
-
-    R = z_elt[ z_elt.keys()[0] ].parent()
-    
-    h = SymmetricFunctionAlgebra(R, basis='h')
-    z = h(0)
-    z._monomial_coefficients = z_elt
-    return z
-
-cdef void* _op_homsym(object d, OP res): #Homogenous symmetric functions
-    cdef OP pointer = res
-    _op_schur_general(d, res)
-    while pointer != NULL:
-        c_o_k(pointer, HOMSYM)
-        pointer = s_s_n(pointer)
-    
-
-cdef object _py_schur_general(OP a):
-    cdef OP pointer = a
-    d = {}
-    if a == NULL:
-        return d
-    while pointer != NULL:
-        d[ _py_partition(s_s_s(pointer)) ] = _py(s_s_k(pointer))
-        pointer = s_s_n(pointer)
-    return d
-
-cdef void* _op_schur_general(object d, OP res):
-    if isinstance(d, dict):
-        _op_schur_general_dict(d, res)
-    else:
-        _op_schur_general_sf(d, res)
-
-cdef void* _op_schur_general_sf(object f, OP res):
-    late_import()
-    base_ring = f.parent().base_ring()
-    if not ( base_ring is QQ or base_ring is ZZ ):
-        raise ValueError, "the base ring must be either ZZ or QQ"
-
-    _op_schur_general_dict( f.monomial_coefficients(), res)
-
-cdef void* _op_schur_general_dict(object d, OP res):
-    late_import()
-
-    cdef OP next
-    cdef OP pointer = res
-    cdef INT n, i
-
-   
-    keys = d.keys()
-    n = len(keys)
-
-    if n == 0:
-        raise ValueError, "the dictionary must be nonempty"
-
-    b_skn_s( callocobject(), callocobject(), NULL, res)
-    _op_partition( keys[0], s_s_s(res))
-    _op( d[keys[0]], s_s_k(res))
-  
-
-    for i from 0 < i < n:
-        next = callocobject()
- 
-        b_skn_s( callocobject(), callocobject(), NULL, next)
-        _op_partition( keys[i], s_s_s(next))
-        _op( d[keys[i]], s_s_k(next))
-
-        insert(next, res, NULL, NULL)
-
-    
-
-######################
-#Schubert Polynomials#
-######################
-cdef void* _op_schubert_general(object d, OP res):
-    if isinstance(d, dict):
-        _op_schubert_dict(d, res)
-    else:
-        _op_schubert_sp(d, res)
-
-cdef void* _op_schubert_perm(object a, OP res):
-    cdef OP caperm = callocobject()
-    _op_permutation(a, caperm)
-    m_perm_sch(caperm, res)
-    freeall(caperm)
-
-cdef void* _op_schubert_sp(object f, OP res):
-    late_import()
-    base_ring = f.parent().base_ring()
-    if not ( base_ring is QQ or base_ring is ZZ ):
-        raise ValueError, "the base ring must be either ZZ or QQ"
-
-    _op_schubert_dict( f.monomial_coefficients(), res)
-
-cdef void* _op_schubert_dict(object d, OP res):
-    late_import()
-
-    cdef OP next
-    cdef OP pointer = res
-    cdef INT n, i
-
-    keys = d.keys()
-    n = len(keys)
-
-    if n == 0:
-        raise ValueError, "the dictionary must be nonempty"
-
-    b_skn_sch( callocobject(), callocobject(), NULL, res)
-    _op_permutation( keys[0], s_sch_s(res))
-    _op( d[keys[0]], s_sch_k(res))
-  
-
-    for i from 0 < i < n:
-        next = callocobject()
- 
-        b_skn_sch( callocobject(), callocobject(), NULL, next)
-        _op_permutation( keys[i], s_sch_s(next))
-        _op( d[keys[i]], s_sch_k(next))
-
-        insert(next, res, NULL, NULL)
-
-cdef object _py_schubert(OP a):
-    late_import()
-    cdef OP pointer = a
-    z_elt = {}
-    
-    if a == NULL:
-        return SchubertPolynomialRing(ZZ)(0)
-    
-    while pointer != NULL:
-        z_elt[ _py_permutation(s_s_s(pointer)) ] = _py(s_sch_k(pointer))
-        pointer = s_sch_n(pointer)
-
-    if len(z_elt) == 0:
-        return SchubertPolynomialRing(ZZ)(0)
-    
-    R = z_elt[ z_elt.keys()[0] ].parent()
-    X = SchubertPolynomialRing(R)
-    z = X(0)
-    z._monomial_coefficients = z_elt
-    return z
-
-
-##########
-#Matrices#
-##########
-cdef object _py_matrix(OP a):
-
-    late_import()
-    
-    cdef INT i,j,rows, cols
-    rows = S_M_HI(a)
-    cols = S_M_LI(a)
-
-    res = []
-    for i from 0 <= i < rows:
-        row = []
-        for j from 0 <= j < cols:
-            row.append( _py(S_M_IJ(a,i,j)) )
-            
-        res.append(row)
-
-    #return res
-    if res == [] or res == None:
-        return res
-    else:
-        return matrix_constructor(res)
-
-
-cdef void* _op_matrix(object a, OP res):
-    #FIXME: only constructs integer matrices
-
-    cdef INT i,j,rows, cols
-
-    rows = a.nrows()
-    cols = a.ncols()
-    
-    m_ilih_m(rows, cols, res)
-
-    for i from 0 <= i < rows:
-        for j from 0 <= j < cols:
-            _op_integer( a[(i,j)], S_M_IJ(res,i,j) ) 
-    
-##########
-#Tableaux#
-##########
-cdef object _py_tableau(OP t):
-
-    late_import()
-    
-    cdef INT i,j,rows, cols
-    cdef OP a
-    a = S_T_S(t)
-    rows = S_M_HI(a)
-    cols = S_M_LI(a)
-
-    res = []
-    for i from 0 <= i < rows:
-        row = []
-        for j from 0 <= j < cols:
-            if s_o_k(S_M_IJ(a,i,j)) == EMPTY:
-                break
-            else:
-                row.append( _py(S_M_IJ(a,i,j)) )
-            
-        res.append(row)
-
-    #return res
-    
-    return Tableau(res)
-
-
-
-
-def start():
-    anfang()
-
-def end():
-    ende()
Index: age/libs/symmetrica/symmetrica.pyx
===================================================================
--- sage/libs/symmetrica/symmetrica.pyx	(revision 6437)
+++ 	(revision )
@@ -1,18 +1,0 @@
-include "../../ext/interrupt.pxi"
-include '../../ext/stdsage.pxi'
-
-include "symmetrica.pxi"
-
-include "kostka.pxi"
-
-include "sab.pxi"
-
-include "sc.pxi"
-
-include "sb.pxi"
-
-include "part.pxi"
-
-include "schur.pxi"
-
-include "plet.pxi"
Index: sage/matrix/matrix_integer_dense.pyx
===================================================================
--- sage/matrix/matrix_integer_dense.pyx	(revision 6441)
+++ sage/matrix/matrix_integer_dense.pyx	(revision 6116)
@@ -1464,72 +1464,4 @@
                 U[i,n-1] = - U[i,n-1]
         return U
-
-    def lll(self, delta=None):
-        r"""
-        Returns LLL reduced lattice R for self.
-
-        The lattice is returned as a matrix. Also the rank (and the
-        determinant) of self are cached.
-
-        More specifically, elementary row transformations are
-        performed on a copy of self so that the non-zero rows of
-        R form an LLL-reduced basis for the lattice spanned by
-        the rows of self. The default reduction parameter is
-        $\delta=3/4$, which means that the squared length of the first
-        non-zero basis vector is no more than $2^{r-1}$ times that of
-        the shortest vector in the lattice.
-
-        For a basis reduced with parameter $\delta$, the squared
-        length of the first non-zero basis vector is no more than
-        $1/(\delta-1/4)^{r-1}$ times that of the shortest vector in
-        the lattice.
-
-        If we can compute the determinant of self using this method,
-        we also cache it. Note that in general this only happens when
-        self.rank() == self.ncols().
-
-        INPUT:
-           delta -- arameter a as described above (default: 3/4)
-
-        OUTPUT:
-            a matrix over the integers
-
-        EXAMPLE:
-            sage: A = Matrix(ZZ,3,3,range(1,10))
-            sage: A.lll()
-            [ 0  0  0]
-            [ 2  1  0]
-            [-1  1  3]
-            
-        ALGORITHM: Uses NTL.
-        """
-
-        import sage.libs.ntl.all
-        ntl_ZZ = sage.libs.ntl.all.ZZ
-
-        if delta is None:
-            delta = ZZ(3)/ZZ(4)
-        elif delta <= ZZ(1)/ZZ(4):
-            raise TypeError, "delta must be > 1/4"
-        elif delta > 1:
-            raise TypeError, "delta must be <= 1/4"
-
-        delta = delta/ZZ(1) # QQ(delta)
-
-        a = delta.numer()
-        b = delta.denom()
-
-        A = sage.libs.ntl.all.mat_ZZ(self.nrows(),self.ncols(),map(ntl_ZZ,self.list()))
-        r, det2 = A.LLL(a,b)
-        r,det2 = ZZ(r), ZZ(det2)
-
-        cdef Matrix_integer_dense R = <Matrix_integer_dense>self.new_matrix(entries=map(ZZ,A.list()))
-        self.cache("rank",r)
-        try:
-            det = ZZ(det2.sqrt_approx())
-            self.cache("det", det)
-        except TypeError:
-            pass
-        return R
 
     def prod_of_row_sums(self, cols):
@@ -2256,4 +2188,18 @@
     return M
 
+##########################################################
+# Setup the c-library and GMP random number generators. 
+# seed it when module is loaded.
+from random import randrange
+cdef extern from "stdlib.h":
+    long random()
+    void srandom(unsigned int seed)
+k = randrange(0,Integer(2)**(32))
+srandom(k)
+
+cdef gmp_randstate_t state
+gmp_randinit_mt(state)
+gmp_randseed_ui(state,k)
+
 #######################################################
 
Index: sage/matrix/matrix_modn_sparse.pxd
===================================================================
--- sage/matrix/matrix_modn_sparse.pxd	(revision 6444)
+++ sage/matrix/matrix_modn_sparse.pxd	(revision 3272)
@@ -7,4 +7,2 @@
     cdef public int p
     cdef swap_rows_c(self, Py_ssize_t n1, Py_ssize_t n2)
-
-    cdef _init_linbox(self)
Index: sage/matrix/matrix_modn_sparse.pyx
===================================================================
--- sage/matrix/matrix_modn_sparse.pyx	(revision 6445)
+++ sage/matrix/matrix_modn_sparse.pyx	(revision 5486)
@@ -80,11 +80,4 @@
 from sage.misc.misc import verbose, get_verbose, graphics_filename
 
-from sage.rings.integer import Integer
-
-from sage.matrix.matrix2 import Matrix as Matrix2
-from sage.rings.arith import is_prime
-
-from sage.structure.element import is_Vector
-
 ################
 # TODO: change this to use extern cdef's methods.
@@ -96,8 +89,4 @@
 import sage.ext.multi_modular
 MAX_MODULUS = sage.ext.multi_modular.MAX_MODULUS
-
-from sage.libs.linbox.linbox cimport Linbox_modn_sparse
-cdef Linbox_modn_sparse linbox
-linbox = Linbox_modn_sparse()
 
 cdef class Matrix_modn_sparse(matrix_sparse.Matrix_sparse):   
@@ -474,262 +463,2 @@
                 k+=1
         return QQ(k)/QQ(self.nrows()*self.ncols())
-
-    def transpose(self):
-        """
-        Return the transpose of self.
-
-        EXAMPLE:
-            sage: A = matrix(GF(127),3,3,[0,1,0,2,0,0,3,0,0],sparse=True)
-            sage: A
-            [0 1 0]
-            [2 0 0]
-            [3 0 0]
-            sage: A.transpose()
-            [0 2 3]
-            [1 0 0]
-            [0 0 0]
-        """
-        cdef int i, j
-        cdef c_vector_modint row
-        cdef Matrix_modn_sparse B
-        
-        B = self.new_matrix(nrows = self.ncols(), ncols = self.nrows())
-        for i from 0 <= i < self._nrows:
-            row = self.rows[i]
-            for j from 0 <= j < row.num_nonzero:
-                set_entry(&B.rows[row.positions[j]], i, row.entries[j])
-        return B
-                                
-    def matrix_from_rows(self, rows):
-        """
-        Return the matrix constructed from self using rows with indices
-        in the rows list.
-
-        INPUT:
-            rows -- list or tuple of row indices
-
-        EXAMPLE:
-            sage: M = MatrixSpace(GF(127),3,3,sparse=True)
-            sage: A = M(range(9)); A
-            [0 1 2]
-            [3 4 5]
-            [6 7 8]
-            sage: A.matrix_from_rows([2,1])
-            [6 7 8]
-            [3 4 5]
-        """
-        cdef int i,k
-        cdef Matrix_modn_sparse A
-        cdef c_vector_modint row
-
-        if not isinstance(rows, (list, tuple)):
-            raise TypeError, "rows must be a list of integers"
-
-
-        A = self.new_matrix(nrows = len(rows))
-
-        k = 0
-        for ii in rows:
-            i = ii
-            if i < 0 or i >= self.nrows():
-                raise IndexError, "row %s out of range"%i
-
-            row = self.rows[i]
-            for j from 0 <= j < row.num_nonzero:
-                set_entry(&A.rows[k], row.positions[j], row.entries[j])
-            k += 1
-        return A
-            
-
-    def matrix_from_columns(self, cols):
-        """
-        Return the matrix constructed from self using columns with
-        indices in the columns list.
-
-        EXAMPLES:
-            sage: M = MatrixSpace(GF(127),3,3,sparse=True)
-            sage: A = M(range(9)); A
-            [0 1 2]
-            [3 4 5]
-            [6 7 8]
-            sage: A.matrix_from_columns([2,1])
-            [2 1]
-            [5 4]
-            [8 7]
-        """
-        cdef int i,j
-        cdef Matrix_modn_sparse A
-        cdef c_vector_modint row
-
-        if not isinstance(cols, (list, tuple)):
-            raise TypeError, "rows must be a list of integers"
-
-        A = self.new_matrix(ncols = len(cols))
-
-        cols = dict(zip([int(e) for e in cols],range(len(cols))))
-
-        for i from 0 <= i < self.nrows():
-            row = self.rows[i]
-            for j from 0 <= j < row.num_nonzero:
-                if int(row.positions[j]) in cols:
-                    set_entry(&A.rows[i], cols[int(row.positions[j])], row.entries[j])
-        return A
-
-    cdef _init_linbox(self):
-        _sig_on
-        linbox.set(self.p, self._nrows, self._ncols,  self.rows)
-        _sig_off
-
-    def _rank_linbox(self, method):
-        """
-        See self.rank().
-        """
-        if is_prime(self.p):
-            x = self.fetch('rank')
-            if not x is None:
-                return x
-            self._init_linbox()
-            _sig_on
-            # the returend pivots list is currently wrong
-            #r, pivots = linbox.rank(1)
-            r = linbox.rank(method)
-            r = Integer(r)
-            _sig_off
-            self.cache('rank', r)
-            return r
-        else:
-            raise TypeError, "only GF(p) supported via LinBox"
-
-    def rank(self, gauss=False):
-        """
-        Compute the rank of self.
-
-        INPUT:
-            gauss -- if True LinBox' Gaussian elimination is used. If False
-                     'Symbolic Reordering' as implemented in LinBox
-                     is used. If 'native' the native SAGE implementation
-                     is used. (default: False)
-
-        EXAMPLE:
-            sage: A = random_matrix(GF(127),200,200,density=0.01,sparse=True)
-            sage: r1 = A.rank(gauss=False)
-            sage: r2 = A.rank(gauss=True)
-            sage: r3 = A.rank(gauss='native')
-            sage: r1 == r2 == r3
-            True
-
-        ALGORITHM: Uses LinBox or native implementation.
-
-        REFERENCES: Jean-Guillaume Dumas and Gilles Villars. 'Computing the
-            Rank of Large Sparse Matrices over Finite Fields'. Proc. CASC'2002,
-            The Fifth International Workshop on Computer Algebra in Scientific Computing,
-            Big Yalta, Crimea, Ukraine, 22-27 sept. 2002, Springer-Verlag,
-            http://perso.ens-lyon.fr/gilles.villard/BIBLIOGRAPHIE/POSTSCRIPT/rankjgd.ps
-
-        NOTE:
-            For very sparse matrices Gaussian elimination is faster because
-            it barly has anything to do. If the fill in needs to be considered,
-            'Symbolic Reordering' is usually much faster.
-        """
-        x = self.fetch('rank')
-        if not x is None: return x
-
-        if is_prime(self.p):
-            if gauss is False:
-                return self._rank_linbox(0)
-            elif gauss is True:
-                return self._rank_linbox(1)
-            elif gauss == "native":
-                return Matrix2.rank(self)
-            else:
-                raise TypeError, "parameter 'gauss' not understood"
-        else:
-            return Matrix2.rank(self)
-
-    def solve_right(self, B, algorithm=None, check_rank = True):
-        """
-        If self is a matrix $A$, then this function returns a vector
-        or matrix $X$ such that $A X = B$.  If $B$ is a vector then
-        $X$ is a vector and if $B$ is a matrix, then $X$ is a matrix.
-
-        NOTE: In SAGE one can also write \code{A \ B} for
-        \code{A.solve_right(B)}, i.e., SAGE implements the ``the
-        MATLAB/Octave backslash operator''.
-
-        INPUT:
-            B -- a matrix or vector
-            algorithm -- one of the following:
-                         'LinBox:BlasElimination' -- dense elimination
-                         'LinBox:Blackbox' -- LinBox chooses a Blackbox algorithm
-                         'LinBox:Wiedemann' -- Wiedemann's algorithm
-                         'generic' -- use generic implementation (inversion)
-                         None -- LinBox chooses an algorithm (default)
-            check_rank -- check rank before attempting to solve (default: True)
-
-        OUTPUT:
-            a matrix or vector
-
-        EXAMPLES:
-            sage: A = matrix(GF(127), 3, [1,2,3,-1,2,5,2,3,1], sparse=True)
-            sage: b = vector(GF(127),[1,2,3])
-            sage: x = A \ b; x
-            (73, 76, 10) 
-            sage: A * x
-            (1, 2, 3)
-
-        """
-        cdef Matrix_modn_sparse A = self
-        cdef Matrix_modn_sparse b
-        cdef Matrix_modn_sparse X
-        cdef c_vector_modint *x
-
-        if algorithm == "generic" or not is_prime(self.p):
-            return Matrix2.solve_right(self, B)
-
-        if check_rank and self.rank() < self.nrows():
-            raise ValueError, "self must be of full rank."
-
-        if not self.is_square():
-            raise NotImplementedError, "input matrix must be square"
-        
-        self._init_linbox()
-
-        matrix = True
-        if is_Vector(B):
-            matrix = False
-            b = <Matrix_modn_sparse>self.matrix_space(1, self.ncols(),sparse=True)(B.list())
-        if PY_TYPE_CHECK(B,Matrix_modn_sparse) and B.base_ring() == self.base_ring():
-            b = <Matrix_modn_sparse>B
-        else:
-            try:
-                b = <Matrix_modn_sparse>self.matrix_space(1, self.ncols(),sparse=True)(B.list())
-            except (TypeError, AttributeError):
-                raise TypeError, "parameter 'b' not understood."
-
-        X = self.new_matrix(b.nrows(),A.ncols())
-
-        if b.nrows() > 1: # such that we can walk through it easily
-            b = b.transpose()
-
-        if algorithm is None:
-            algorithm = 0
-        elif algorithm == "LinBox:BlasElimination":
-            algorithm = 1
-        elif algorithm == "LinBox:Blackbox":
-            algorithm = 2
-        elif algorithm == "LinBox:Wiedemann":
-            algorithm = 3
-        else:
-            raise TypeError, "parameter 'algorithm' not understood"
-
-        for i in range(X.nrows()):
-            _sig_on
-            x = &X.rows[i]
-            linbox.solve(&x, &b.rows[i], algorithm)
-            _sig_off
-
-        if not matrix:
-            # Convert back to a vector
-            return (X.base_ring() ** X.ncols())(X.list())
-        else:
-            return X.transpose()
Index: sage/matrix/matrix_rational_dense.pyx
===================================================================
--- sage/matrix/matrix_rational_dense.pyx	(revision 6409)
+++ sage/matrix/matrix_rational_dense.pyx	(revision 6262)
@@ -897,5 +897,5 @@
     ################################################
     def echelonize(self, algorithm='default',
-                   height_guess=None, proof=None, **kwds):
+                   height_guess=None, proof=True, **kwds):
         """
         INPUT:
@@ -904,9 +904,6 @@
                          'multimodular': uses a multimodular algorithm the uses linbox
                                          modulo many primes.
-            height_guess, **kwds -- all passed to the multimodular algorithm; ignored
+            height_guess, proof, **kwds -- all passed to the multimodular algorithm; ignored
                                            by the p-adic algorithm.
-            proof -- bool or None (default: None, see proof.linear_algebra or
-                         sage.structure.proof).  Passed to the multimodular algorithm.
-                         Note that the Sage global default is proof=True.
 
         OUTPUT:
@@ -952,5 +949,5 @@
 
     def echelon_form(self, algorithm='default',
-                     height_guess=None, proof=None, **kwds):
+                     height_guess=None, proof=True, **kwds):
         """
         INPUT:
@@ -959,9 +956,6 @@
                          'multimodular': uses a multimodular algorithm the uses linbox
                                          modulo many primes.
-            height_guess, **kwds -- all passed to the multimodular algorithm; ignored
+            height_guess, proof, **kwds -- all passed to the multimodular algorithm; ignored
                                            by the p-adic algorithm.
-            proof -- bool or None (default: None, see proof.linear_algebra or
-                         sage.structure.proof).  Passed to the multimodular algorithm.
-                         Note that the Sage global default is proof=True.
 
         OUTPUT:
@@ -1093,5 +1087,5 @@
         
     # Multimodular echelonization algorithms
-    def _echelonize_multimodular(self, height_guess=None, proof=None, **kwds):
+    def _echelonize_multimodular(self, height_guess=None, proof=True, **kwds):
         cdef Matrix_rational_dense E
         E = self._echelon_form_multimodular(height_guess, proof=proof, **kwds)            
@@ -1105,5 +1099,5 @@
         return E.pivots()
 
-    def _echelon_form_multimodular(self, height_guess=None, proof=None):
+    def _echelon_form_multimodular(self, height_guess=None, proof=True):
         """
         Returns reduced row-echelon form using a multi-modular
@@ -1114,7 +1108,5 @@
         INPUT:
             height_guess -- integer or None
-            proof -- boolean (default: None, see proof.linear_algebra or
-                         sage.structure.proof)
-                         Note that the Sage global default is proof=True.
+            proof -- boolean (default: True)
         """
         import misc
@@ -1123,5 +1115,5 @@
 
     def decomposition(self, is_diagonalizable=False, dual=False,
-                      algorithm='default', height_guess=None, proof=None):
+                      algorithm='default', height_guess=None, proof=True):
         """
         Returns the decomposition of the free module on which this
@@ -1153,7 +1145,5 @@
                          'multimodular': much better if the answers factors have small height
             height_guess -- positive integer; only used by the multimodular algorithm
-            proof -- bool or None (default: None, see proof.linear_algebra or
-                         sage.structure.proof); only used by the multimodular algorithm.
-                         Note that the Sage global default is proof=True.
+            proof -- bool (default: True); only used by the multimodular algorithm
 
         IMPORTANT NOTE:
Index: sage/matrix/matrix_space.py
===================================================================
--- sage/matrix/matrix_space.py	(revision 6451)
+++ sage/matrix/matrix_space.py	(revision 5928)
@@ -22,6 +22,4 @@
     [0 0]
 """
-
-import types
 
 # System imports
@@ -624,5 +622,5 @@
             [ 0 -1]
         """
-        if isinstance(x, (types.GeneratorType, xrange)):
+        if isinstance(x, (xrange,xsrange)):
             x = list(x)
         elif isinstance(x, (int, integer.Integer)) and x==1:
Index: sage/matrix/misc.pyx
===================================================================
--- sage/matrix/misc.pyx	(revision 6409)
+++ sage/matrix/misc.pyx	(revision 4103)
@@ -272,5 +272,5 @@
 
 
-def matrix_rational_echelon_form_multimodular(Matrix self, height_guess=None, proof=None):
+def matrix_rational_echelon_form_multimodular(Matrix self, height_guess=None, proof=True):
     """
     Returns reduced row-echelon form using a multi-modular
@@ -281,7 +281,5 @@
     INPUT:
         height_guess -- integer or None
-        proof -- boolean or None (default: None, see proof.linear_algebra or
-                               sage.structure.proof).
-                        Note that the global Sage default is proof=True
+        proof -- boolean (default: True)
 
     ALGORITHM:
@@ -322,8 +320,4 @@
         a few more primes.
     """
-
-    if proof is None:
-        from sage.structure.proof.proof import get_flag
-        proof = get_flag(proof, "linear_algebra")
 
     verbose("Multimodular echelon algorithm on %s x %s matrix"%(self._nrows, self._ncols), caller_name="multimod echelon")
Index: sage/misc/all.py
===================================================================
--- sage/misc/all.py	(revision 6416)
+++ sage/misc/all.py	(revision 6271)
@@ -1,3 +1,3 @@
-from misc import (alarm, ellipsis_range, ellipsis_iter, srange, xsrange, sxrange, getitem,
+from misc import (alarm, srange, xsrange, sxrange, getitem,
                   cputime, verbose, set_verbose, set_verbose_files,
                   get_verbose_files, unset_verbose_files, get_verbose, 
@@ -30,5 +30,5 @@
 from hg import hg_sage, hg_doc, hg_scripts, hg_extcode
 
-from package import install_package, standard_packages, optional_packages, experimental_packages, upgrade
+from package import install_package, optional_packages, upgrade
 
 from pager import pager
Index: sage/misc/cython.py
===================================================================
--- sage/misc/cython.py	(revision 6384)
+++ sage/misc/cython.py	(revision 5513)
@@ -119,6 +119,6 @@
 def cython(filename, verbose=False, compile_message=False,
           use_cache=False, create_local_c_file=False):
-    if not filename.endswith('pyx'):
-        print "File (=%s) should have extension .pyx"%filename
+    if filename[-5:] != '.spyx':
+        print "File (=%s) must have extension .spyx"%filename
 
     clean_filename = sanitize(filename)
@@ -204,5 +204,5 @@
     cython_include = ' '.join(['-I %s'%x for x in includes if len(x.strip()) > 0 ])
 
-    cmd = 'cd %s && cython -p --pre-import sage.all %s %s.pyx 1>log 2>err '%(build_dir, cython_include, name)
+    cmd = 'cd %s && cython -p %s %s.pyx 1>log 2>err '%(build_dir, cython_include, name)
 
     if create_local_c_file:
Index: sage/misc/flatten.py
===================================================================
--- sage/misc/flatten.py	(revision 6325)
+++ sage/misc/flatten.py	(revision 5205)
@@ -34,5 +34,5 @@
 
    Degenerate cases:
-      sage: flatten([[],[]])
+      sage: flatten([[]])
       []
       sage: flatten([[[]]])
@@ -48,5 +48,4 @@
          else:
             new_list.pop(index)
-            index -= 1
             break
       index += 1
Index: sage/misc/interpreter.py
===================================================================
--- sage/misc/interpreter.py	(revision 6349)
+++ sage/misc/interpreter.py	(revision 5830)
@@ -177,5 +177,5 @@
     line = line.rstrip()
 
-    if not line.startswith('attach ') and not line.startswith('load '):
+    if not line[:7] == 'attach ' and not line[:5] == 'load ':
         for F in attached.keys():
             tm = attached[F]
@@ -183,9 +183,9 @@
                 # Reload F.
                 try:
-                    if F.endswith('.py'):
+                    if F[-3:] == '.py':
                         _ip.magic('run -i "%s"'%F)
-                    elif F.endswith('.sage'):
+                    elif F[-5:] == '.sage':
                         _ip.magic('run -i "%s"'%process_file(F))
-                    elif F.endswith('.spyx') or F.endswith('.pyx'):
+                    elif F[-5:] == '.spyx':
                         X = load_cython(F)
                         __IPYTHON__.push(X)
@@ -268,6 +268,6 @@
         if isinstance(name, str):
             if not os.path.exists(name):
-                raise ImportError, "File '%s' not found (be sure to give .sage, .py, or .pyx extension)"%name
-            elif name.endswith('.py'):
+                raise ImportError, "File '%s' not found (be sure to give .sage, .py, or .spyx extension)"%name
+            elif name[-3:] == '.py':
                 try:
                     line = '%run -i "' + name + '"'
@@ -275,5 +275,5 @@
                     print s
                     raise ImportError, "Error loading '%s'"%name
-            elif name.endswith('.sage'):
+            elif name[-5:] == '.sage':
                 try:
                     line = '%run -i "' + process_file(name) + '"'
@@ -282,9 +282,9 @@
                     raise ImportError, "Error loading '%s'"%name
                     line = ""
-            elif name.endswith('.spyx') or name.endswith('.pyx'):
+            elif name[-5:] == '.spyx':
                 line = load_cython(name)
             else:
                 line = 'load("%s")'%name
-                #raise ImportError, "Loading of '%s' not implemented (load .py, .pyx, and .sage files)"%name
+                #raise ImportError, "Loading of '%s' not implemented (load .py, .spyx, and .sage files)"%name
                 #line = ''
 
@@ -313,5 +313,5 @@
     # better.  It is very nice for interactive code development.
     
-    if line.startswith('attach '):
+    if line[:7] == 'attach ':
         # The -i so the file is run with the same environment,
         # e.g., including the "from sage import *"
@@ -322,6 +322,6 @@
         name = os.path.abspath(name)
         if not os.path.exists(name):
-            raise ImportError, "File '%s' not found  (be sure to give .sage, .py, or .pyx extension)."%name
-        elif name.endswith('.py'):
+            raise ImportError, "File '%s' not found  (be sure to give .sage, .py, or .spyx extension)."%name
+        elif name[-3:] == '.py':
             try:
                 line = '%run -i "' + name + '"'
@@ -329,5 +329,5 @@
             except IOError, OSError:
                 raise ImportError, "File '%s' not found."%name
-        elif name.endswith('.sage'):
+        elif name[-5:] == '.sage':
             try:
                 line = '%run -i "' + process_file(name) + '"'
@@ -335,5 +335,5 @@
             except IOError, OSError:
                 raise ImportError, "File '%s' not found."%name
-        elif name.endswith('.pyx') or name.endswith('.spyx'):
+        elif name[-5:] == '.spyx':
             try:
                 line = load_cython(name)
@@ -344,5 +344,5 @@
         else:
             #line = 'load("%s")'%name
-            raise ImportError, "Attaching of '%s' not implemented (load .py, .pyx, and .sage files)"%name
+            raise ImportError, "Attaching of '%s' not implemented (load .py, .spyx, and .sage files)"%name
         
     if len(line) > 0:
Index: sage/misc/misc.py
===================================================================
--- sage/misc/misc.py	(revision 6449)
+++ sage/misc/misc.py	(revision 5944)
@@ -6,5 +6,4 @@
     -- William Stein (2006-04-26): added workaround for Windows where 
             most users's home directory has a space in it. 
-    -- Robert Bradshaw (2007-09-20): Ellipsis range/iterator. 
 """
 
@@ -620,10 +619,10 @@
         attr = "_" + z[len(x.__module__)+1:] + attr
     x.__dict__[attr] = init
-    
-#################################################################
-# Ranges and [1,2,..,n] notation. 
-#################################################################
-
-def srange(start, end=None, step=1, universe=None, check=True, include_endpoint=False):
+
+#################################################################
+# Useful but hard to classify
+#################################################################
+
+def srange(a,b=None,step=1, include_endpoint=False):
     """
     Return list of numbers \code{a, a+step, ..., a+k*step},
@@ -677,43 +676,40 @@
         sage: R = RealField()
         sage: srange(1,5,R('0.5'))
-        [1.00000000000000, 1.50000000000000, 2.00000000000000, 2.50000000000000, 3.00000000000000, 3.50000000000000, 4.00000000000000, 4.50000000000000]
+        [1, 1.50000000000000, 2.00000000000000, 2.50000000000000, 3.00000000000000, 3.50000000000000, 4.00000000000000, 4.50000000000000]
         sage: srange(0,1,R('0.4'))
-        [0.000000000000000, 0.400000000000000, 0.800000000000000]
-    """
-    from sage.structure.sequence import Sequence
-    from sage.rings.all import ZZ
-    if end is None:
-        end = start
-        start = 0
-    if check:
-        if universe is None:
-            universe = Sequence([start, end, step]).universe()
-        start, end, step = universe(start), universe(end), universe(step)
-    if include_endpoint:
-        if universe in [int, long, ZZ]:
-            if (start-end) % step == 0:
-                end += step
-        elif (start-end)/step in ZZ:
-            end += step
-    if universe is int:
-        return range(start, end, step)
-    elif universe is ZZ:
-        return ZZ.range(start, end, step)
-    else:
-        L = []
-        if step > 0:
-            while start < end:
-                L.append(start)
-                start += step
-        elif step < 0:
-            while start > end:
-                L.append(start)
-                start += step
+        [0, 0.400000000000000, 0.800000000000000]
+    """
+    if b is None:
+        b = a
+        try:
+            a = b.parent()(0)
+        except AttributeError:
+            a = type(b)(0)
+        
+    if step == 0:
+        raise ValueError, "step size must be nonzero"
+    num_steps = int(float((b-a)/step)) + 1
+    if num_steps <= 0:
+        return []
+    v = [a] + [a + k*step for k in range(1,num_steps)]
+
+    if step > 0:
+        if v[num_steps-1] >= b:
+            if include_endpoint:
+                return v[:-1] + [b]
+            else:
+                return v[:-1]
         else:
-            raise ValueError, "step must not be 0"
-        return L
-
-
-def xsrange(start, end=None, step=1, universe=None, check=True, include_endpoint=False):
+            return v
+    elif step < 0:
+        if v[num_steps-1] <= b:
+            if include_endpoint:
+                return v[:-1] + [b]
+            else:
+                return v[:-1]
+        else:
+            return v
+
+class xsrange:
     """
     Return an iterator over numbers \code{a, a+step, ..., a+k*step},
@@ -745,7 +741,7 @@
         sage: R = RealField()
         sage: list(xsrange(1, 5, R(0.5)))
-        [1.00000000000000, 1.50000000000000, 2.00000000000000, 2.50000000000000, 3.00000000000000, 3.50000000000000, 4.00000000000000, 4.50000000000000]
+        [1, 1.50000000000000, 2.00000000000000, 2.50000000000000, 3.00000000000000, 3.50000000000000, 4.00000000000000, 4.50000000000000]
         sage: list(xsrange(0, 1, R('0.4')))
-        [0.000000000000000, 0.400000000000000, 0.800000000000000]
+        [0, 0.400000000000000, 0.800000000000000]
 
     Negative ranges are also allowed:
@@ -757,138 +753,27 @@
         [4, 7/2, 3, 5/2, 2, 3/2]
     """
-    if end is None:
-        end = start
-        start = 0
-    if step == 0:
-        raise ValueError, "step must not be 0"
-    from sage.structure.sequence import Sequence
-    from sage.rings.all import ZZ
-    if check:
-        if universe is None:
-            universe = Sequence([start, end, step]).universe()
-        start, end, step = universe(start), universe(end), universe(step)
-    if include_endpoint:
-        if universe in [int, long, ZZ]:
-            if (start-end) % step == 0:
-                end += step
-        elif (start-end)/step in ZZ:
-            end += step
-    if universe is int:
-        return xrange(start, end, step)
-#    elif universe is ZZ:
-#        return ZZ.xrange(start, end, step)
-    else:
-        return generic_xsrange(start, end, step)
+    def __init__(self, a, b=None, step=1):
+        self.__a = a
+        self.__b = b
+        if step == 0:
+            raise ValueError, 'sxrange() arg 3 must not be zero'
+        self.__step = step
+
+    def __repr__(self):
+        return 'xrange(%s, %s, %s)'%(self.__a, self.__b, self.__step)
+
+    def __len__(self):
+        if self.__b is None:
+            return int(self.__a / self.__step)
+        n = int((self.__b - self.__a) / self.__step)
+        if n < 0:
+            return 0
+        return n
         
-
-def generic_xsrange(start, end, step):
-    if step > 0:
-        while start < end:
-            yield start
-            start += step
-    else:
-        while start > end:
-            yield start
-            start += step
+    def __iter__(self):
+        return _xsrange(self.__a, self.__b, self.__step)
 
 sxrange = xsrange
     
-    
-def ellipsis_range(*args):
-    """
-    Return arithmatic sequence determined by the numeric arguments and 
-    ellipsis. Best illistrated by examples. 
-    
-    Use [1,2,..,n] notation. 
-    
-    EXAMPLES: 
-        sage: ellipsis_range(1,Ellipsis,11,100)
-        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 100]
-        sage: ellipsis_range(0,2,Ellipsis,10,Ellipsis,20)
-        [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
-        sage: ellipsis_range(0,2,Ellipsis,11,Ellipsis,20)
-        [0, 2, 4, 6, 8, 10, 11, 13, 15, 17, 19]
-    """
-    from sage.structure.sequence import Sequence
-    S = Sequence([a for a in args if a is not Ellipsis])
-    universe = S.universe()
-    args = [Ellipsis if a is Ellipsis else universe(a) for a in args]
-    
-    diff = universe(1)
-    if Ellipsis in args:
-        i = args.index(Ellipsis)
-        if i > 1:
-            diff = args[i-1]-args[i-2]
-    
-    skip = False
-    L = []
-    for i in range(len(args)):
-        if skip:
-            skip = False
-        elif args[i] is Ellipsis:
-            if i > 2 and args[i-2] is Ellipsis and L[-1] != args[i-1]:
-                L.append(args[i-1])
-            L += srange(args[i-1]+diff, args[i+1]+1, diff, universe=universe, check=False)
-            skip = True
-        else:
-            L.append(args[i])
-    return L
-    
-
-def ellipsis_iter(*args):
-    """
-    Same as ellipsis_range, but as an iterator (and may end with an Ellipsis). 
-    
-    Use (1,2,...) notation. 
-    
-    EXAMPLES: 
-        sage: A = ellipsis_iter(1,2,Ellipsis)
-        sage: [A.next() for _ in ra