# HG changeset patch
# User Franco Saliola <saliola@gmail.com>
# Date 1247865591 -7200
# Node ID 3ba698f579d60b3012f878bd351bb28e047ea7fc
# Parent  dc22b8baa725a961a260c720b1a7244cc3111188
imported patch words_ng-picklejar-support.patch

diff -r dc22b8baa725 -r 3ba698f579d6 sage/combinat/words/utils.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sage/combinat/words/utils.py	Fri Jul 17 23:19:51 2009 +0200
@@ -0,0 +1,377 @@
+"""
+Word utilities (DEPRECATED) 
+
+.. note::
+
+    This module will be deleted in a future version of Sage. Most of the
+    commands here have been already deleted; only the commands needed for
+    unpickling word objects saved with older versions of Sage (pre 4.1) have
+    been kept (for now).
+
+"""
+#*****************************************************************************
+#       Copyright (C) 2008 Arnaud Bergeron <abergeron@gmail.com>
+#
+#  Distributed under the terms of the GNU General Public License version 2 (GPLv2)
+#
+#  The full text of the GPLv2 is available at:
+#
+#                  http://www.gnu.org/licenses/
+#*****************************************************************************
+from itertools import islice, tee, izip, starmap, imap, ifilter, ifilterfalse
+from copy import copy
+
+def copy_it(it):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Copy an iterator using its builtin __copy__ method if
+    available, otherwise use itertools.tee(). Define __copy__ for
+    your iterators. (See PEP 323)
+    
+    TESTS::
+    
+        sage: from sage.combinat.words.utils import copy_it
+        sage: it = iter([1, 2, 3, 4, 5])
+        sage: it, it2 = copy_it(it)
+        sage: list(it)
+        [1, 2, 3, 4, 5]
+        sage: it2.next()
+        1
+        sage: it2, it3 = copy_it(it2)
+        sage: list(it2)
+        [2, 3, 4, 5]
+        sage: it3.next()
+        2
+    """
+    it = iter(it)
+    if hasattr(it, '__copy__'):
+        return (it, copy(it))
+    else:    
+        return tee(it)
+
+def slice_it(it, l, key):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Slice an iterator, supporting negative step sizes by expliciting
+    the elements if needed.
+    
+    NOTE: The iterator returned depends on it. You must pass in a copy
+    of your iterator if you intend to keep using the original
+    iterator.
+    
+    TESTS::
+    
+        sage: from sage.combinat.words.utils import slice_it
+        sage: list(slice_it(iter(range(5)), 5, slice(None)))
+        [0, 1, 2, 3, 4]
+        sage: list(slice_it(iter(range(5)), 5, slice(3)))
+        [0, 1, 2]
+        sage: list(slice_it(iter(range(5)), 5, slice(-1)))
+        [0, 1, 2, 3]
+        sage: list(slice_it(iter(range(5)), 5, slice(2, 4)))
+        [2, 3]
+        sage: list(slice_it(iter(range(5)), 5, slice(3, 1, -1)))
+        [3, 2]
+    """
+    start, stop, step = key.start, key.stop, key.step
+    if step is None:
+        step = 1
+    if step == 0:
+        raise ValueError, "attempt to use 0 as step value"
+    elif step > 0:
+        return islice(it, *slice_indices(key, l))
+    else:
+        return tuple(islice(it, l))[key]
+
+def peek_it(it):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Returns the first element of an iterator and returns an iterator at
+    the same position as the original iterator
+    
+    EXAMPLES::
+    
+        sage: from sage.combinat.words.utils import peek_it
+        sage: it = iter([1, 2, 3])
+        sage: it, n = peek_it(it); n
+        1
+        sage: it.next()
+        1
+    """
+    it, cp = copy_it(it)
+    return it, cp.next()
+
+def len_it(it):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Returns the number of elements in it.
+    
+    This function will modify the iterator, so if you want to access
+    the elements later, make a copy of the iterator and pass it to this
+    function.
+    
+    EXAMPLES::
+    
+        sage: from sage.combinat.words.utils import len_it
+        sage: len_it(iter([1, 2, 3]))
+        3
+    """
+    n = 0
+    try:
+        while True:
+            it.next()
+            n += 1
+    except StopIteration:
+        return n
+
+def haslen(obj):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Returns true if obj has a properly defined length
+    
+    EXAMPLES::
+    
+        sage: from sage.combinat.words.utils import haslen
+        sage: haslen([1, 2, 3])
+        True
+        sage: haslen(33)
+        False
+    
+    TESTS::
+    
+        sage: class test(object):
+        ...     def __len__(self):
+        ...         return -1
+        ...
+        sage: haslen(test())
+        False
+    """
+    try:
+        len(obj)
+    except:
+        return False
+    return True
+    
+def sliceable(obj):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Returns true if obj is completely sliceable, including negative
+    step sizes
+    
+    EXAMPLES::
+    
+        sage: from sage.combinat.words.utils import sliceable
+        sage: sliceable([1, 2, 3])
+        True
+        sage: sliceable(33)
+        False
+    
+    TESTS::
+    
+        sage: class test(object):
+        ...     def __getitem__(self, key):
+        ...         return islice(iter([1]), *key)
+        ...
+        sage: sliceable(test())
+        False
+    """
+    try:
+        obj[0:0:-1]
+    except:
+        return False
+    return True
+
+def isint(obj):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Returns True if obj is an integer or a custom object representing
+    an integer and False otherwise.
+    
+    EXAMPLES::
+    
+        sage: from sage.combinat.words.utils import isint
+        sage: isint(1)
+        True
+        sage: isint("2")
+        False
+        sage: isint(1.0)
+        False
+    """
+    return hasattr(obj, '__index__')
+
+def is_iterable(obj):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Returns true if the obj is iterable.
+    
+    EXAMPLES::
+    
+        sage: from sage.combinat.words.utils import is_iterable
+        sage: is_iterable('123')
+        True
+        sage: is_iterable([1, 2, 3])
+        True
+        sage: is_iterable(xrange(1, 4))
+        True
+        sage: is_iterable(33)
+        False
+    """
+    try:
+        iter(obj)
+        return True
+    except:
+        return False
+
+def slice_ok(part):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Returns true if part is a slice and doesn't have funny values.
+    
+    EXAMPLES::
+    
+        sage: from sage.combinat.words.utils import slice_ok
+        sage: slice_ok(slice(None))
+        True
+        sage: slice_ok(slice(2))
+        True
+        sage: slice_ok(slice(1, 2, 3))
+        True
+        sage: slice_ok(slice(None, 2, 3))
+        True
+        sage: slice_ok(slice(1, None, 3))
+        True
+        sage: slice_ok(slice(1, 2, None))
+        True
+        sage: slice_ok(slice("a"))
+        False
+        sage: slice_ok(slice("a", 1))
+        False
+        sage: slice_ok(slice(1, 2, "a"))
+        False
+        sage: slice_ok(1)
+        False
+    """
+    return isinstance(part, slice) and \
+           (part.start is None or isint(part.start)) and \
+           (part.stop is None or isint(part.stop)) and \
+           (part.step is None or isint(part.step))
+
+def slice_indices(s, l):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Implement slice.indices without bugs.
+    
+    TESTS::
+    
+        sage: from sage.combinat.words.utils import slice_indices
+        sage: slice_indices(slice(None), 8)
+        (0, 8, 1)
+        sage: slice_indices(slice(1), 8)
+        (0, 1, 1)
+        sage: slice_indices(slice(10), 8)
+        (0, 8, 1)
+        sage: slice_indices(slice(-4), 8)
+        (0, 4, 1)
+        sage: slice_indices(slice(-10), 8)
+        (0, 0, 1)
+        sage: slice_indices(slice(1, None), 8)
+        (1, 8, 1)
+        sage: slice_indices(slice(10, None), 8)
+        (8, 8, 1)
+        sage: slice_indices(slice(-4, None), 8)
+        (4, 8, 1)
+        sage: slice_indices(slice(-10, None), 8)
+        (0, 8, 1)
+        sage: slice_indices(slice(None, None, 2), 8)
+        (0, 8, 2)
+        sage: slice_indices(slice(None, None, -2), 8)
+        (7, -1, -2)
+    """
+    start, stop, step = s.indices(l)
+    if stop*step < start*step:
+        stop = start
+    return start, stop, step
+
+def reverse_map(d):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Return a new dict with swapped keys and values
+    
+    EXAMPLES::
+    
+        sage: from sage.combinat.words.utils import reverse_map
+        sage: reverse_map({'a': 1, 'b': 2}) == {1: 'a', 2: 'b'}
+        True
+    """
+    return dict(izip(d.itervalues(), d))
+
+def id_f(x):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Dummy identity function for when a function is required but none is
+    desired.
+    
+    .. note::
+
+       This function is needed required so that words saved in earlier versions
+       of Sage can be loaded; and will be deleted in a future version of Sage. 
+
+    TESTS::
+    
+        sage: from sage.combinat.words.utils import id_f
+        sage: l = [1, 2, 3]
+        sage: l is id_f(l)
+        True
+    """
+    return x
+
+def clamp(x, min, max):
+    r"""
+    This function is deprecated and will be deleted in a future
+    version of Sage.
+
+    Clamp a value between a maximum and a minimum.
+    
+    EXAMPLES::
+    
+        sage: from sage.combinat.words.utils import clamp
+        sage: clamp(0, -1, 1)
+        0
+        sage: clamp(-2, 0, 4)
+        0
+        sage: clamp(10, 0, 4)
+        4
+    """
+    if x < min:
+        return min
+    elif x > max:
+        return max
+    else:
+        return x
+
+from sage.combinat.words.word import Factorization
+
diff -r dc22b8baa725 -r 3ba698f579d6 sage/combinat/words/word.py
--- a/sage/combinat/words/word.py	Fri Jul 17 23:19:35 2009 +0200
+++ b/sage/combinat/words/word.py	Fri Jul 17 23:19:51 2009 +0200
@@ -366,6 +366,9 @@
             datatype = "callable"
         elif hasattr(data,"__iter__"):
             datatype = "iter"
+        elif isinstance(data, WordContent):
+            # For backwards compatibility (picklejar)
+            return _word_from_word_content(data=data, parent=alphabet)
         else:
             raise ValueError, "Cannot guess a datatype; please specify one"
     else:
@@ -378,8 +381,6 @@
                                 "callable", "iter"):
             raise ValueError, "Unknown datatype"
 
-    #print 'datatype:', datatype
-
     # Create the parent object
     from words import Words
     parent = Words() if alphabet is None else Words(alphabet)
@@ -436,7 +437,7 @@
 
 ###########################################################################
 ##### DEPRECATION WARNINGS ################################################
-##### Added 10 February 2008 ##############################################
+##### Added July 2009 #####################################################
 ###########################################################################
 
 def is_Word(obj):
@@ -1084,7 +1085,7 @@
 
             sage: w = Word('abaccefa')
             sage: w._word_content
-            doctest:492: DeprecationWarning: _word_content is deprecated! try to_integer_word instead! See the documentation for more information
+            doctest:...: DeprecationWarning: _word_content is deprecated! try to_integer_word instead! See the documentation for more information
             word: 01022340
         """
         from sage.misc.misc import deprecation
@@ -1460,7 +1461,7 @@
 
     ###########################################################################
     ##### DEPRECATION WARNINGS (next 4 functions) #############################
-    ##### Added 23 February 2008 ##############################################
+    ##### Added July 2009 #####################################################
     ###########################################################################
     def is_suffix_of(self, other):
         r"""
@@ -1498,7 +1499,7 @@
             sage: W = Word
             sage: W('23').is_proper_suffix_of(W('123'))
             doctest:1: DeprecationWarning: is_proper_suffix_of is deprecated, use is_proper_suffix instead!
-            doctest:1604: DeprecationWarning: is_suffix_of is deprecated, use is_suffix instead!
+            doctest:...: DeprecationWarning: is_suffix_of is deprecated, use is_suffix instead!
             True
             sage: W('12').is_proper_suffix_of(W('12'))
             False
@@ -1545,7 +1546,7 @@
             sage: W = Word
             sage: W('12').is_proper_prefix_of(W('123'))
             doctest:1: DeprecationWarning: is_proper_prefix_of is deprecated, use is_proper_prefix instead!
-            doctest:1689: DeprecationWarning: is_prefix_of is deprecated, use is_prefix instead!
+            doctest:...: DeprecationWarning: is_prefix_of is deprecated, use is_prefix instead!
             True
             sage: W('12').is_proper_prefix_of(W('12'))
             False
@@ -2392,7 +2393,7 @@
             
     ###########################################################################
     ##### DEPRECATION WARNINGS ################################################
-    ##### Added 12 February 2008 ##############################################
+    ##### Added July 2009 #####################################################
     ###########################################################################
     def _lps(self, l=None, f=None):
         r"""
@@ -3639,7 +3640,7 @@
 
     ###########################################################################
     ##### DEPRECATION WARNINGS ################################################
-    ##### Added 23 February 2008 ##############################################
+    ##### Added July 2009 #####################################################
     ###########################################################################
     def last_position_table(self):
         r"""
@@ -3721,7 +3722,7 @@
 
     ###########################################################################
     ##### DEPRECATION WARNINGS ################################################
-    ##### Added 23 February 2008 ##############################################
+    ##### Added July 2009 #####################################################
     ###########################################################################
     def is_factor_of(self, other):
         r"""
@@ -3993,7 +3994,7 @@
         
     ###########################################################################
     ##### DEPRECATION WARNINGS ################################################
-    ##### Added 23 February 2008 ##############################################
+    ##### Added July 2009 #####################################################
     ###########################################################################
     def _quasiperiods_list(self):
         r"""
@@ -4115,7 +4116,7 @@
 
     ###########################################################################
     ##### DEPRECATION WARNINGS ################################################
-    ##### Added 23 February 2008 ##############################################
+    ##### Added July 2009 #####################################################
     ###########################################################################
     def freq(self):
         r"""
@@ -4503,7 +4504,7 @@
 
     ###########################################################################
     ##### DEPRECATION WARNINGS ################################################
-    ##### Added 23 February 2008 ##############################################
+    ##### Added July 2009 #####################################################
     ###########################################################################
     def iterated_palindromic_closure(self, side='right', f=None):
         r"""
@@ -5763,32 +5764,114 @@
 #                                                                     #
 #######################################################################
 
+def _word_from_word_content(data, parent):
+    r"""
+    Create a word with the given parent from a :class:`WordContent` object.
+
+    .. note::
+
+       :class:`WordContent` is deprecated and will be deleted in a future
+       version of Sage. This function exists to maintain backwards
+       compatibility for unpickling objects saved with older versions of Sage.
+
+    TESTS::
+
+        sage: from sage.combinat.words.word import _word_from_word_content
+        sage: import sage.combinat.words.word_content as word_content
+        sage: cl = word_content.WordContentFromList([0, 1, 1, 2, 1])
+        doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        sage: _word_from_word_content(cl,Words([0,1,2]))
+        word: 01121
+        sage: _word_from_word_content(cl,Words([2,1,0]))
+        word: 21101
+
+    ::
+
+        sage: cf = word_content.WordContentFromFunction(lambda x : x)[:10]
+        doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        sage: _word_from_word_content(cf, Words())
+        word: 0123456789
+
+    ::
+
+        sage: from itertools import count
+        sage: ci = word_content.WordContentFromIterator(count(3))[:5]
+        doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        sage: _word_from_word_content(ci, Words())
+        word: 34567
+
+    ::
+
+        sage: cc = word_content.ConcatenateContent((cl, cf, ci))
+        doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        sage: _word_from_word_content(cc, Words())
+        word: 01121012345678934567
+
+    """
+    from sage.combinat.words import word_content
+    # extract data from WordContent object
+    length = None
+    if isinstance(data, word_content.WordContentFromList):
+        unranker = parent.alphabet().unrank
+        data = map(unranker, data._list)
+        datatype = 'list'
+    elif isinstance(data, word_content.WordContentFromIterator):
+        data = data._get_it()
+        datatype = 'iter'
+    elif isinstance(data, word_content.WordContentFromFunction):
+        length = data._len
+        data = data._func
+        datatype = 'callable'
+    elif isinstance(data, word_content.ConcatenateContent):
+        l = map(_word_from_word_content, data)
+        data = CallableFromListOfWords(l)
+        datatype = 'callable'
+    else:
+        raise TypeError, 'data is not an instance of WordContent'
+    return Word(data=data, alphabet=parent, datatype=datatype, length=length)
+
 class DeprecatedWordClass(SageObject):
-    def __new__(cls, parent, word, mapping=None, format=None, part=slice(None)):
-        from sage.misc.misc import deprecation
-        deprecation("%s is deprecated, use %s instead!" % (cls.__name__,
-            cls.__bases__[1].__name__))
-        return parent(data=word, format=format, part=part)
-
-class AbstractWord(DeprecatedWordClass, Word_class):
-    pass
-
-class AbstractFiniteWord(DeprecatedWordClass, FiniteWord_class):
+    def __setstate__(self, data):
+        from sage.misc.misc import deprecation
+        cls = self.__class__
+        deprecation('Your word object is saved in an old file format '
+            'since %s is deprecated and will be deleted in a future version '
+            'of Sage (you can use %s instead). You can re-save your word by '
+            'typing "word.save(filename)" to ensure that it will load in '
+            'future versions of Sage.''' %
+            (cls.__name__, cls.__bases__[1].__name__))
+        parent = data['_parent']
+        del data['_parent']
+        wordcontent = data.get('_word_content', None)
+        del data['_word_content']
+        w = _word_from_word_content(wordcontent, parent)
+        self.__class__ = type(w)
+        self.__init__(parent, list(w))
+        for key, item in data.iteritems():
+            setattr(self, key, item)
+
+class AbstractWord(DeprecatedWordClass, FiniteWord_list):
+    pass
+
+class AbstractFiniteWord(DeprecatedWordClass, FiniteWord_list):
     pass
 
 class AbstractInfiniteWord(DeprecatedWordClass, InfiniteWord_class):
     pass
 
-class Word_over_Alphabet(DeprecatedWordClass, Word_class):
-    pass
-
-class Word_over_OrderedAlphabet(DeprecatedWordClass, Word_class):
-    pass
-
-class FiniteWord_over_Alphabet(DeprecatedWordClass, FiniteWord_class):
-    pass
-
-class FiniteWord_over_OrderedAlphabet(DeprecatedWordClass, FiniteWord_class):
+class Word_over_Alphabet(DeprecatedWordClass, FiniteWord_list):
+    pass
+
+class Word_over_OrderedAlphabet(DeprecatedWordClass, FiniteWord_list):
+    pass
+
+class FiniteWord_over_Alphabet(DeprecatedWordClass, FiniteWord_list):
+    pass
+
+class FiniteWord_over_OrderedAlphabet(DeprecatedWordClass, FiniteWord_list):
     pass
 
 class InfiniteWord_over_Alphabet(DeprecatedWordClass, InfiniteWord_class):
diff -r dc22b8baa725 -r 3ba698f579d6 sage/combinat/words/word_content.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sage/combinat/words/word_content.py	Fri Jul 17 23:19:51 2009 +0200
@@ -0,0 +1,960 @@
+# coding=utf-8
+"""
+Word contents (DEPRECATED) 
+
+.. note::
+
+    This module will be deleted in a future version of Sage. Most of the
+    commands here have been already deleted; only the commands needed for
+    unpickling word objects saved with older versions of Sage (pre 4.1) have
+    been kept (for now).
+
+"""
+#*****************************************************************************
+#       Copyright (C) 2008 Arnaud Bergeron <abergeron@gmail.com>,
+#
+#  Distributed under the terms of the GNU General Public License version 2 (GPLv2)
+#
+#  The full text of the GPLv2 is available at:
+#
+#                  http://www.gnu.org/licenses/
+#*****************************************************************************
+from itertools import imap, izip, count
+from sage.rings.infinity import Infinity
+from sage.combinat.words.utils import *
+
+def BuildWordContent(obj, mapping=id_f, format=None, part=slice(None)):
+    r"""
+    Builds the content for a word.
+    
+    INPUT:
+    
+    
+    -  ``obj`` - a function, an iterator or a list,
+       potentially with a length defined
+    
+    -  ``mapping`` - function, a map sending elements of
+       the iterable to nonnegative integers.
+    
+    -  ``format`` - string (default None), the explicit
+       type of obj. Can be either 'empty', 'list', 'function' or
+       'iterator'. If set to None (the default), the type will be guessed
+       from the properties of obj.
+    
+    -  ``part`` - slice (default slice(None)), the portion
+       of the object to use
+    
+    
+    OUTPUT:
+    
+    
+    -  ``word content`` - an object respecting the word
+       content protocol wrapping obj
+    
+    
+    TESTS::
+    
+        sage: from sage.combinat.words.word_content import BuildWordContent
+        sage: from itertools import count, imap, repeat
+        sage: len(BuildWordContent(None))
+        doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        0
+        sage: len(BuildWordContent(None, format='empty'))
+        0
+        sage: c = BuildWordContent(['a', 'b'], format='empty')
+        Traceback (most recent call last):
+        ...
+        TypeError: trying to build an empty word with something other than None
+        sage: len(BuildWordContent(['0', '1', '1'], int))
+        doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        3
+        sage: len(BuildWordContent(['0', '1', '1'], int, format='list'))
+        3
+        sage: BuildWordContent(10, format='list')
+        Traceback (most recent call last):
+        ...
+        TypeError: trying to build a word backed by a list with a sequence not providing the required operations
+        sage: c = BuildWordContent(lambda x: x%2)
+        doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        sage: len(BuildWordContent(lambda x: x%3, part=slice(0,10)))
+        10
+        sage: c = BuildWordContent(repeat(1))
+        doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        sage: len(BuildWordContent(count(), part=slice(10)))
+        10
+        sage: len(BuildWordContent(count(), part=slice(10, 0, -2)))
+        doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        5
+    """
+    if format is None:
+        if isinstance(obj, WordContent):
+            return obj[part]
+        elif obj is None:
+            format = 'empty'
+        elif is_iterable(obj):
+            if haslen(obj):
+                format = 'list'
+            else:
+                format = 'iterator'
+        elif callable(obj):
+            format = 'function'
+        else:
+            pass # Don't set format if we don't know
+
+    if format == 'empty':
+        if obj is not None:
+            raise TypeError, "trying to build an empty word with something other than None"
+        return WordContentFromList((), mapping)[part]
+    elif format == 'list' or format == 'string':
+        if not (is_iterable(obj) and haslen(obj)):
+            raise TypeError, "trying to build a word backed by a list with a sequence not providing the required operations"
+        return WordContentFromList(obj, mapping)[part]
+    elif format == 'function':
+        if not callable(obj):
+            raise TypeError, "trying to build a word backed by a function with a non-callable"
+        return WordContentFromFunction(obj, mapping)[part]
+    elif format == 'iterator':
+        if not is_iterable(obj):
+            raise TypeError, "trying to build a word backed by an iterator with a non-iterable"
+        return WordContentFromIterator(obj, mapping)[part]
+    raise NotImplementedError
+
+def is_WordContent(obj):
+    r"""
+    Returns True if obj is the content of a word.
+    
+    EXAMPLES::
+    
+        sage: from sage.combinat.words.word_content import BuildWordContent, is_WordContent
+        sage: is_WordContent(33)
+        False
+        sage: is_WordContent(BuildWordContent([0, 1, 0], lambda x : x))
+        True
+    """
+    return isinstance(obj, WordContent)
+
+class WordContent(object):
+    def __cmp__(self, other):
+        r"""
+        Compares two contents according to the data they contain.
+        
+        The types of the contents doesn't matter.
+        
+        TESTS::
+        
+            sage: c1 = sage.combinat.words.word_content.WordContentFromList([1, 2, 1, 1])
+            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: c2 = sage.combinat.words.word_content.WordContentFromList([1, 2, 3])
+            sage: c3 = sage.combinat.words.word_content.WordContentFromList([1, 4])
+            sage: c2.__cmp__(c1) > 0
+            True
+            sage: c2.__cmp__(c2) == 0
+            True
+            sage: c2.__cmp__(c3) < 0
+            True
+        """
+        if not is_WordContent(other):
+            return NotImplemented
+        if haslen(self) and haslen(other):
+            for (i, j) in izip(self, other):
+                if i != j:
+                    return i - j
+            return len(self) - len(other)
+        return NotImplemented
+    
+    def concatenate(self, other):
+        r"""
+        Method to concatenate two contents together.
+        
+        TESTS::
+        
+            sage: from sage.combinat.words.word_content import BuildWordContent
+            sage: list(BuildWordContent([1]).concatenate(BuildWordContent([2, 3, 4])))
+            doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            [1, 2, 3, 4]
+        """
+        if not (haslen(self) and haslen(other)):
+            raise ValueError, "cannot concatenate infinite words"
+        return ConcatenateContent(self._get_list() + other._get_list())
+    
+    def _get_list(self):
+        r"""
+        Returns self as a list of contents suitable for concatenate
+        
+        TESTS::
+        
+            sage: type(sage.combinat.words.word_content.BuildWordContent([1, 2, 3])._get_list())
+            <type 'tuple'>
+        """
+        return (self,)
+    
+    def _check_getitem_args(self, key):
+        r"""
+        Does all the type and range checking for the key argument to
+        __getitem__(). Also takes care of normalizing the ranges
+        specified by slicing to values suitable for xrange() or similar in
+        the finite case. In the infinite case a stop value of None, will
+        stay as None since no end can be defined.
+        
+        TESTS: Generic Cases
+        
+        ::
+        
+            sage: w = sage.combinat.words.word_content.WordContent()
+            sage: w._check_getitem_args(1)
+            1
+            sage: w._check_getitem_args("abc")
+            Traceback (most recent call last):
+            ...
+            TypeError: word indices must be integers
+            sage: w._check_getitem_args(slice(1, 2, 3))
+            slice(1, 2, 3)
+            sage: w._check_getitem_args(slice("a"))
+            Traceback (most recent call last):
+            ...
+            TypeError: word indices must be integers
+            sage: w._check_getitem_args(slice("a", 1))
+            Traceback (most recent call last):
+            ...
+            TypeError: word indices must be integers
+            sage: w._check_getitem_args(slice(1, 1, "a"))
+            Traceback (most recent call last):
+            ...
+            TypeError: word indices must be integers
+        
+        Finite Cases
+        
+        ::
+        
+            sage: f = sage.combinat.words.word_content.WordContentFromList(range(10))
+            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: f._check_getitem_args(slice(None, None, None))
+            slice(0, 10, 1)
+            sage: f._check_getitem_args(slice(None, 0, None))
+            slice(0, 0, 1)
+            sage: f._check_getitem_args(slice(None, 1, None))
+            slice(0, 1, 1)
+            sage: f._check_getitem_args(slice(None, -1, None))
+            slice(0, 9, 1)
+            sage: f._check_getitem_args(slice(None, 11, None))
+            slice(0, 10, 1)
+            sage: f._check_getitem_args(slice(None, 10, None))
+            slice(0, 10, 1)
+            sage: f._check_getitem_args(slice(None, 9, None))
+            slice(0, 9, 1)
+            sage: f._check_getitem_args(slice(None, -9, None))
+            slice(0, 1, 1)
+            sage: f._check_getitem_args(slice(None, -10, None))
+            slice(0, 0, 1)
+            sage: f._check_getitem_args(slice(None, -11, None))
+            slice(0, 0, 1)
+            sage: f._check_getitem_args(slice(0, None, None))
+            slice(0, 10, 1)
+            sage: f._check_getitem_args(slice(1, None, None))
+            slice(1, 10, 1)
+            sage: f._check_getitem_args(slice(-1, None, None))
+            slice(9, 10, 1)
+            sage: f._check_getitem_args(slice(11, None, None))
+            slice(10, 10, 1)
+            sage: f._check_getitem_args(slice(10, None, None))
+            slice(10, 10, 1)
+            sage: f._check_getitem_args(slice(9, None, None))
+            slice(9, 10, 1)
+            sage: f._check_getitem_args(slice(-9, None, None))
+            slice(1, 10, 1)
+            sage: f._check_getitem_args(slice(-10, None, None))
+            slice(0, 10, 1)
+            sage: f._check_getitem_args(slice(-11, None, None))
+            slice(0, 10, 1)
+            sage: f._check_getitem_args(slice(None, None, -1))
+            slice(9, -1, -1)
+            sage: f._check_getitem_args(slice(None, 0, -1))
+            slice(9, 0, -1)
+            sage: f._check_getitem_args(slice(None, 1, -1))
+            slice(9, 1, -1)
+            sage: f._check_getitem_args(slice(None, -1, -1))
+            slice(9, 9, -1)
+            sage: f._check_getitem_args(slice(None, 11, -1))
+            slice(9, 9, -1)
+            sage: f._check_getitem_args(slice(None, 10, -1))
+            slice(9, 9, -1)
+            sage: f._check_getitem_args(slice(None, 9, -1))
+            slice(9, 9, -1)
+            sage: f._check_getitem_args(slice(None, -10, -1))
+            slice(9, 0, -1)
+            sage: f._check_getitem_args(slice(None, -11, -1))
+            slice(9, -1, -1)
+            sage: f._check_getitem_args(slice(None, -12, -1))
+            slice(9, -1, -1)
+            sage: f._check_getitem_args(slice(0, None, -1))
+            slice(0, -1, -1)
+            sage: f._check_getitem_args(slice(1, None, -1))
+            slice(1, -1, -1)
+            sage: f._check_getitem_args(slice(-1, None, -1))
+            slice(9, -1, -1)
+            sage: f._check_getitem_args(slice(10, None, -1))
+            slice(9, -1, -1)
+            sage: f._check_getitem_args(slice(9, None, -1))
+            slice(9, -1, -1)
+            sage: f._check_getitem_args(slice(8, None, -1))
+            slice(8, -1, -1)
+            sage: f._check_getitem_args(slice(-10, None, -1))
+            slice(0, -1, -1)
+            sage: f._check_getitem_args(slice(-11, None, -1))
+            slice(-1, -1, -1)
+            sage: f._check_getitem_args(slice(-12, None, -1))
+            slice(-1, -1, -1)
+            sage: f._check_getitem_args(slice(None, None, 0))
+            Traceback (most recent call last):
+            ...
+            ValueError: slice step cannot be zero
+            sage: f._check_getitem_args(9)
+            9
+            sage: f._check_getitem_args(10)
+            Traceback (most recent call last):
+            ...
+            IndexError: word index out of range
+            sage: f._check_getitem_args(0)
+            0
+            sage: f._check_getitem_args(-1)
+            9
+            sage: f._check_getitem_args(-10)
+            0
+            sage: f._check_getitem_args(-11)
+            Traceback (most recent call last):
+            ...
+            IndexError: word index out of range
+        
+        Infinite Cases
+        
+        ::
+        
+            sage: from itertools import count
+            sage: i = sage.combinat.words.word_content.WordContentFromIterator(count())
+            doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: i._check_getitem_args(slice(None, None, None))
+            slice(0, None, 1)
+            sage: i._check_getitem_args(slice(None, 0, None))
+            slice(0, 0, 1)
+            sage: i._check_getitem_args(slice(None, 1, None))
+            slice(0, 1, 1)
+            sage: i._check_getitem_args(slice(None, -1, None))
+            Traceback (most recent call last):
+            ...
+            IndexError: negative index on infinite word
+            sage: i._check_getitem_args(slice(0, None, None))
+            slice(0, None, 1)
+            sage: i._check_getitem_args(slice(1, None, None))
+            slice(1, None, 1)
+            sage: i._check_getitem_args(slice(-1, None, None))
+            Traceback (most recent call last):
+            ...
+            IndexError: negative index on infinite word
+            sage: i._check_getitem_args(slice(None, None, -1))
+            Traceback (most recent call last):
+            ...
+            ValueError: negative step and no defined start
+            sage: i._check_getitem_args(slice(None, 0, -1))
+            Traceback (most recent call last):
+            ...
+            ValueError: negative step and no defined start
+            sage: i._check_getitem_args(slice(None, -1, -1))
+            Traceback (most recent call last):
+            ...
+            ValueError: negative step and no defined start
+            sage: i._check_getitem_args(slice(0, None, -1))
+            slice(0, -1, -1)
+            sage: i._check_getitem_args(slice(-1, None, -1))
+            Traceback (most recent call last):
+            ...
+            IndexError: negative index on infinite word
+            sage: i._check_getitem_args(slice(None, None, 0))
+            Traceback (most recent call last):
+            ...
+            ValueError: slice step cannot be zero
+            sage: i._check_getitem_args(1)
+            1
+            sage: i._check_getitem_args(-1)
+            Traceback (most recent call last):
+            ...
+            IndexError: negative index on infinite word
+        """
+        if slice_ok(key):
+            start, stop, step = key.start, key.stop, key.step
+            if step is None:
+                step = 1
+            if step == 0:
+                raise ValueError, "slice step cannot be zero"
+            if haslen(self):
+                if start is None:
+                    if step < 0:
+                        start = len(self) - 1
+                    else:
+                        start = 0
+                else:
+                    if start < 0:
+                        start += len(self)
+                    if step < 0:
+                        start = clamp(start, -1, len(self) - 1)
+                    else:
+                        start = clamp(start, 0, len(self))
+                if stop is None:
+                    if step < 0:
+                        stop = -1
+                    else:
+                        stop = len(self)
+                else:
+                    if stop < 0:
+                        stop += len(self)
+                    if step < 0:
+                        stop = clamp(stop, -1, len(self) - 1)
+                    else:
+                        stop = clamp(stop, 0, len(self))
+            else:
+                if start is None:
+                    if step < 0:
+                        raise ValueError, "negative step and no defined start"
+                    else:
+                        start = 0
+                else:
+                    start = self._check_getitem_args(start)
+                if stop is None:
+                    if step < 0:
+                       stop = -1
+                else:
+                    stop = self._check_getitem_args(stop)
+            return slice(start, stop, step)
+        elif isint(key):
+            key = int(key)
+            if haslen(self):
+                if key < 0:
+                    key += len(self)
+                if key < 0 or key >= len(self):
+                    raise IndexError, "word index out of range"
+            else:
+                if key < 0:
+                    raise IndexError, "negative index on infinite word"
+            return key
+        else:
+            raise TypeError, "word indices must be integers"
+
+class WordContentFromList(WordContent):
+    def __init__(self, l, trans=id_f):
+        r"""
+        INPUT:
+        
+        
+        -  ``l`` - list
+        
+        -  ``trans`` - function (default identity), defines a
+           mapping between the objects in l and the nonnegative integers
+        
+        
+        TESTS::
+        
+            sage: c = sage.combinat.words.word_content.WordContentFromList([0, 1, 1, 2, 1])
+            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: c == loads(dumps(c))
+            True
+        """
+        from sage.misc.misc import deprecation
+        deprecation('%s is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives' % self.__class__.__name__)
+        self._list = map(trans, l)
+    
+    def __iter__(self):
+        r"""
+        TESTS::
+        
+            sage: list(sage.combinat.words.word_content.WordContentFromList('012345', int)) # indirect test
+            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            [0, 1, 2, 3, 4, 5]
+        """
+        return iter(self._list)
+    
+    def __len__(self):
+        r"""
+        TESTS::
+        
+            sage: len(sage.combinat.words.word_content.WordContentFromList([0, 1, 0, 0, 1]))
+            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            5
+        """
+        return len(self._list)
+    
+    def __getitem__(self, key):
+        r"""
+        TESTS::
+        
+            sage: from sage.combinat.words.word_content import WordContentFromList
+            sage: w = WordContentFromList('012345', int)
+            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: e = WordContentFromList('', int)
+            sage: w__2 = WordContentFromList('45', int)
+            sage: w_2 = WordContentFromList('01', int)
+            sage: w__1 = WordContentFromList('01234', int)
+            sage: w_s2 = WordContentFromList('024', int)
+            sage: w_s_2 = WordContentFromList('531', int)
+            sage: w[:] == w
+            True
+            sage: w[0:] == w
+            True
+            sage: w[10:] == e
+            True
+            sage: w[-2:] == w__2
+            True
+            sage: w[-10:] == w
+            True
+            sage: w[:0] == e
+            True
+            sage: w[:2] == w_2
+            True
+            sage: w[:10] == w
+            True
+            sage: w[:-1] == w__1
+            True
+            sage: w[:-10] == e
+            True
+            sage: w[::2] == w_s2
+            True
+            sage: w[::-2] == w_s_2
+            True
+            sage: w[::0]
+            Traceback (most recent call last):
+            ...
+            ValueError: slice step cannot be zero
+            sage: w[0]
+            0
+            sage: w[5]
+            5
+            sage: w[6]
+            Traceback (most recent call last):
+            ...
+            IndexError: word index out of range
+            sage: w[-1]
+            5
+            sage: w[-6]
+            0
+            sage: w[-7]
+            Traceback (most recent call last):
+            ...
+            IndexError: word index out of range
+        """
+        key = self._check_getitem_args(key)
+        if isinstance(key, slice):
+            if key.stop == -1:
+                key = slice(key.start, None, key.step)
+            return WordContentFromList(self._list[key])
+        else:
+            return self._list[key]
+
+class WordContentFromFunction(WordContent):
+    def __init__(self, func, trans=id_f):
+        r"""
+        INPUT:
+        
+        
+        -  ``func`` - callable
+        
+        -  ``trans`` - callable (default: identity), defines a
+           mapping between the objects returned by func and the nonnegative
+           integers.
+        
+        
+        NOTE: Unnamed functions do not pickle. And if you arbitrarily slice
+        this type of container then it may use lambdas and break pickling.
+        
+        TESTS::
+        
+            sage: c = sage.combinat.words.word_content.WordContentFromFunction(sage.combinat.words.utils.id_f)[:10]
+            doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: c == loads(dumps(c))
+            True
+        """
+        from sage.misc.misc import deprecation
+        deprecation('%s is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives' % self.__class__.__name__)
+        self._func = func
+        self._len = Infinity
+        self._trans = trans
+    
+    def __iter__(self):
+        r"""
+        TESTS::
+        
+            sage: list(sage.combinat.words.word_content.WordContentFromFunction(sage.combinat.words.utils.id_f)[:6]) # indirect test
+            doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            [0, 1, 2, 3, 4, 5]
+        """
+        for i in xrange(self._len) if haslen(self) else count():
+            yield self._trans(self._func(i))
+    
+    def __len__(self):
+        r"""
+        TESTS::
+        
+            sage: c = sage.combinat.words.word_content.WordContentFromFunction(sage.combinat.words.utils.id_f)
+            doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: len(c)
+            Traceback (most recent call last):
+            ...
+            TypeError: an integer is required
+            sage: c = c[:10]
+            sage: len(c)
+            10
+        """
+        return self._len
+    
+    def __getitem__(self, key):
+        r"""
+        TESTS::
+        
+            sage: from sage.combinat.words.utils import id_f
+            sage: from sage.combinat.words.word_content import WordContentFromFunction, WordContentFromList
+            sage: w = WordContentFromFunction(id_f);
+            doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: e = WordContentFromList('', int)
+            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: w__2 = WordContentFromList('45', int)
+            sage: w_2 = WordContentFromList('01', int)
+            sage: w__1 = WordContentFromList('01234', int)
+            sage: w_s2 = WordContentFromList('024', int)
+            sage: w_s_2 = WordContentFromList('531', int)
+            sage: w[:]          # random results
+            <sage.combinat.words.word_content.WordContentFromFunction object at 0xe499c30>
+            sage: w[0:]         # random results
+            <sage.combinat.words.word_content.WordContentFromFunction object at 0xe499c50>
+            sage: w[1:]         # random results
+            <sage.combinat.words.word_content.WordContentFromFunction object at 0xe499c30>
+            sage: w[:0] == e
+            True
+            sage: w[:5] == w__1
+            True
+            sage: w[::2]        # random results
+            <sage.combinat.words.word_content.WordContentFromFunction object at 0xe499bf0>
+            sage: w[::0]
+            Traceback (most recent call last):
+            ...
+            ValueError: slice step cannot be zero
+            sage: w[5]
+            5
+            sage: w[-1]
+            Traceback (most recent call last):
+            ...
+            IndexError: negative index on infinite word
+            sage: w._len = 6
+            sage: w[:] == w
+            True
+            sage: w[0:] == w
+            True
+            sage: w[10:] == e
+            True
+            sage: w[-2:] == w__2
+            True
+            sage: w[-10:] == w
+            True
+            sage: w[:0] == e
+            True
+            sage: w[:2] == w_2
+            True
+            sage: w[:10] == w
+            True
+            sage: w[:-1] == w__1
+            True
+            sage: w[:-10] == e
+            True
+            sage: w[::2] == w_s2
+            True
+            sage: w[::-2] == w_s_2
+            True
+            sage: w[::0]
+            Traceback (most recent call last):
+            ...
+            ValueError: slice step cannot be zero
+            sage: w[0]
+            0
+            sage: w[5]
+            5
+            sage: w[6]
+            Traceback (most recent call last):
+            ...
+            IndexError: word index out of range
+            sage: w[-1]
+            5
+            sage: w[-6]
+            0
+            sage: w[-7]
+            Traceback (most recent call last):
+            ...
+            IndexError: word index out of range
+        """
+        key = self._check_getitem_args(key)
+        if isinstance(key, slice):
+            if key.start != 0 or key.step != 1:
+                # TODO: maybe use an accessory class for the slicing
+                fn = lambda x: self._func(key.start + x*key.step)
+            else:
+                fn = self._func
+            res = WordContentFromFunction(fn, self._trans)
+            if key.stop is not None:
+                res._len = int((key.stop - key.start)/key.step)
+            return res
+        else:
+            return self._trans(self._func(key))
+
+class WordContentFromIterator(WordContent):
+    def __init__(self, it, trans=id_f):
+        r"""
+        INPUT:
+        
+        
+        -  ``it`` - iterator
+        
+        -  ``trans`` - function (default identity), defines a
+           mapping between the objects returned by it and the nonnegative
+           integers.
+        
+        
+        NOTE: It appears that islice does not pickle correctly causing
+        various errors when reloading. Also, most iterators do not support
+        copying and should not support pickling by extension.
+        
+        TESTS::
+        
+            sage: from itertools import count
+            sage: c = sage.combinat.words.word_content.WordContentFromIterator(count())[:10]
+            doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+        
+        ::
+        
+            #sage: c == loads(dumps(c)) # broken because of islice
+            #True
+        """
+        from sage.misc.misc import deprecation
+        deprecation('%s is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives' % self.__class__.__name__)
+        self._iter = iter(it)
+        self._len = Infinity
+        self._trans = trans
+    
+    def __iter__(self):
+        r"""
+        TESTS::
+        
+            sage: from itertools import count
+            sage: list(sage.combinat.words.word_content.WordContentFromIterator(count())[:6]) # indirect test
+            doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            [0, 1, 2, 3, 4, 5]
+        """
+        return imap(self._trans, self._get_it())
+    
+    def _get_it(self):
+        r"""
+        TESTS::
+        
+            sage: from itertools import count
+            sage: c = sage.combinat.words.word_content.WordContentFromIterator(count())
+            doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: it1 = c._get_it()
+            sage: it2 = c._get_it()
+            sage: it1.next()
+            0
+            sage: it2.next()
+            0
+            sage: list(c[:4])
+            [0, 1, 2, 3]
+            sage: it1.next()
+            1
+            sage: it2.next()
+            1
+        """
+        self._iter, new = copy_it(self._iter)
+        return new
+    
+    def __len__(self):
+        r"""
+        TESTS::
+        
+            sage: from itertools import count
+            sage: c = sage.combinat.words.word_content.WordContentFromIterator(count())
+            doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: len(c)
+            Traceback (most recent call last):
+            ...
+            TypeError: an integer is required
+            sage: c = c[:10]
+            sage: len(c)
+            10
+        """
+        return self._len
+    
+    def __getitem__(self, key):
+        r"""
+        TESTS::
+        
+            sage: from itertools import count
+            sage: from sage.combinat.words.word_content import WordContentFromIterator, WordContentFromList
+            sage: w = WordContentFromIterator(count())
+            doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: e = WordContentFromList('', int)
+            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: w__2 = WordContentFromList('45', int)
+            sage: w_2 = WordContentFromList('01', int)
+            sage: w__1 = WordContentFromList('01234', int)
+            sage: w_s2 = WordContentFromList('024', int)
+            sage: w_s_2 = WordContentFromList('531', int)
+            sage: w[:]          # random results
+            <sage.combinat.words.word_content.WordContentFromIterator object at 0xe499c30>
+            sage: w[0:]         # random results
+            <sage.combinat.words.word_content.WordContentFromIterator object at 0xe499c50>
+            sage: w[1:]         # random results
+            <sage.combinat.words.word_content.WordContentFromIterator object at 0xe499c30>
+            sage: w[:0] == e
+            True
+            sage: w[:5] == w__1
+            True
+            sage: w[::2]        # random results
+            <sage.combinat.words.word_content.WordContentFromIterator object at 0xe499bf0>
+            sage: w[::0]
+            Traceback (most recent call last):
+            ...
+            ValueError: slice step cannot be zero
+            sage: w[5]
+            5
+            sage: w[-1]
+            Traceback (most recent call last):
+            ...
+            IndexError: negative index on infinite word
+            sage: w._len = 6
+            sage: w[:] == w
+            True
+            sage: w[0:] == w
+            True
+            sage: w[10:] == e
+            True
+            sage: w[-2:] == w__2
+            True
+            sage: w[-10:] == w
+            True
+            sage: w[:0] == e
+            True
+            sage: w[:2] == w_2
+            True
+            sage: w[:10] == w
+            True
+            sage: w[:-1] == w__1
+            True
+            sage: w[:-10] == e
+            True
+            sage: w[::2] == w_s2
+            True
+            sage: w[::-2] == w_s_2
+            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            True
+            sage: w[::0]
+            Traceback (most recent call last):
+            ...
+            ValueError: slice step cannot be zero
+            sage: w[0]
+            0
+            sage: w[5]
+            5
+            sage: w[6]
+            Traceback (most recent call last):
+            ...
+            IndexError: word index out of range
+            sage: w[-1]
+            5
+            sage: w[-6]
+            0
+            sage: w[-7]
+            Traceback (most recent call last):
+            ...
+            IndexError: word index out of range
+        """
+        key = self._check_getitem_args(key)
+        if isinstance(key, slice):
+            if key.step < 0:
+                if key.stop == -1:
+                    key = slice(key.start, None, key.step)
+                if haslen(self):
+                    return WordContentFromList(slice_it(self, len(self), key))
+                else:
+                    return WordContentFromList(slice_it(self, \
+                                int(key.start - key.stop), key))
+            else:
+                res = WordContentFromIterator(islice(self._get_it(), key.start, \
+                                              key.stop, key.step), self._trans)
+                if key.stop is not None:
+                    res._len = int((key.stop - key.start)/key.step)
+                return res
+        else:
+            return islice(self, key, None).next()
+
+class ConcatenateContent(WordContentFromFunction):
+    r"""
+    Class that acts as a function to concatenate contents.
+    """
+    def __init__(self, l):
+        r"""
+        TESTS::
+        
+            sage: from sage.combinat.words.word_content import ConcatenateContent, BuildWordContent
+            sage: c = ConcatenateContent((BuildWordContent([1, 2]),))
+            doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: len(c)
+            2
+            sage: c = ConcatenateContent((BuildWordContent('1221', int), BuildWordContent('2112', int)))
+            sage: len(c)
+            8
+        """
+        from sage.misc.misc import deprecation
+        deprecation('%s is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives' % self.__class__.__name__)
+        self._list = l
+        super(ConcatenateContent, self).__init__(self)
+        self._len = sum(imap(len, self._list))
+    
+    def __iter__(self):
+        r"""
+        TESTS::
+        
+            sage: from sage.combinat.words.word_content import ConcatenateContent, BuildWordContent
+            sage: list(ConcatenateContent((BuildWordContent('012', int), BuildWordContent([3, 4, 5])))) # indirect test
+            doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            [0, 1, 2, 3, 4, 5]
+        """
+        for c in self._list:
+            for s in c:
+                yield s
+    
+    def _get_list(self):
+        r"""
+        Optimization: for ConcatenateContents return the internal list.
+        
+        TESTS::
+        
+            sage: from sage.combinat.words.word_content import ConcatenateContent, BuildWordContent
+            sage: type(ConcatenateContent((BuildWordContent([1, 2]),))._get_list())
+            doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            <type 'tuple'>
+        """
+        return self._list
+    
+    def __call__(self, key):
+        r"""
+        Returns the character at position key in the word.
+        
+        EXAMPLES::
+        
+            sage: from sage.combinat.words.word_content import ConcatenateContent, BuildWordContent
+            sage: c = ConcatenateContent((BuildWordContent('1221', int), BuildWordContent('2112', int)))
+            doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
+            sage: c(0)
+            1
+            sage: c(7)
+            2
+        """
+        for c in self._list:
+            if (key - len(c) < 0):
+                return c[key]
+            key -= len(c)
diff -r dc22b8baa725 -r 3ba698f579d6 sage/combinat/words/words.py
--- a/sage/combinat/words/words.py	Fri Jul 17 23:19:35 2009 +0200
+++ b/sage/combinat/words/words.py	Fri Jul 17 23:19:51 2009 +0200
@@ -1007,7 +1007,7 @@
 
 ###########################################################################
 ##### DEPRECATION WARNINGS ################################################
-##### Added 5 February 2008 ###############################################
+##### Added July 2009 #####################################################
 ###########################################################################
 
 def is_Words(obj):
