diff -r 54342f65c59c sage/libs/singular/function.pxd
--- a/sage/libs/singular/function.pxd	Thu Jul 15 11:38:43 2010 +0200
+++ b/sage/libs/singular/function.pxd	Thu Jul 15 23:00:43 2010 +0200
@@ -24,7 +24,7 @@
 
 cdef class Resolution:
     cdef syStrategy *_resolution
-    cdef MPolynomialRing_libsingular base_ring
+    cdef object base_ring
 
 cdef class Converter(SageObject):
     cdef leftv *args
@@ -44,7 +44,7 @@
     cdef leftv * append_intvec(self, v) except NULL
     cdef leftv * append_list(self, l) except NULL
     cdef leftv * append_matrix(self, a) except NULL
-    cdef leftv * append_ring(self, MPolynomialRing_libsingular r) except NULL
+    cdef leftv * append_ring(self, r) except NULL
     cdef leftv * append_module(self, m) except NULL
     cdef to_sage_integer_matrix(self, intvec *mat)
     cdef object to_sage_module_element_sequence_destructive(self, ideal *i)
@@ -70,7 +70,7 @@
 
     cdef BaseCallHandler get_call_handler(self)
     cdef bint function_exists(self)
-    cdef MPolynomialRing_libsingular common_ring(self, tuple args, ring=?)
+    cdef common_ring(self, tuple args, ring=?)
 
 cdef class SingularLibraryFunction(SingularFunction):
     pass
diff -r 54342f65c59c sage/libs/singular/function.pyx
--- a/sage/libs/singular/function.pyx	Thu Jul 15 11:38:43 2010 +0200
+++ b/sage/libs/singular/function.pyx	Thu Jul 15 23:00:43 2010 +0200
@@ -13,6 +13,7 @@
 - Martin Albrecht (2009-07): clean up, enhancements, etc.
 - Michael Brickenstein (2009-10): extension to more Singular types
 - Martin Albrecht (2010-01): clean up, support for attributes
+- Burcin Erocal (2010-7): plural support
 
 EXAMPLES:
 
@@ -81,7 +82,7 @@
 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular
 
 from sage.rings.polynomial.plural cimport NCPolynomialRing_plural, \
-        NCPolynomial_plural
+        NCPolynomial_plural, new_NCP
 from sage.rings.polynomial.multi_polynomial_ideal import NCPolynomialIdeal
 
 from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal
@@ -122,8 +123,7 @@
     
     for (i, p) in enumerate(v):
         component = <int>i+1
-        poly_component = p_Copy(
-            (<MPolynomial_libsingular>p)._poly, r)
+        poly_component = copy_sage_polynomial_into_singular_poly(p)
         p_iter = poly_component
         while p_iter!=NULL:
             p_SetComp(p_iter, component, r)
@@ -132,6 +132,7 @@
         res=p_Add_q(res, poly_component, r)
     return res
 
+
 cdef class RingWrap:
     """
     A simple wrapper around Singular's rings.
@@ -170,8 +171,9 @@
            sage: M = syz(I)
            sage: resolution = mres(M, 0)
         """
-        assert PY_TYPE_CHECK(base_ring, MPolynomialRing_libsingular)
-        self.base_ring = <MPolynomialRing_libsingular> base_ring
+        #FIXME: still not working noncommutative
+        assert is_sage_wrapper_for_singular_ring(base_ring)
+        self.base_ring = base_ring
     def __repr__(self):
         """
         EXAMPLE::
@@ -229,6 +231,27 @@
     args.CleanUp()
     omFreeBin(args, sleftv_bin)
 
+# =====================================
+# = Singular/Plural Abstraction Layer =
+# =====================================
+
+def is_sage_wrapper_for_singular_ring(ring):
+    if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
+        return True
+    if PY_TYPE_CHECK(ring, NCPolynomialRing_plural):
+        return True
+    return False
+
+cdef new_sage_polynomial(ring,  poly *p):
+    if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
+        return new_MP(ring, p)
+    else:
+        if PY_TYPE_CHECK(ring, NCPolynomialRing_plural):
+            return new_NCP(ring, p)
+    raise ValueError("not a singular or plural ring")
+
+def is_polynomial(p):
+    return PY_TYPE_CHECK(p, MPolynomial_libsingular) or PY_TYPE_CHECK(p,  NCPolynomial_plural)
 
 def all_polynomials(s):
     """
@@ -245,10 +268,28 @@
         False
     """
     for p in s:
-        if not isinstance(p, MPolynomial_libsingular):
+        if not is_polynomial(p):
             return False
     return True
 
+cdef poly* access_singular_poly(p) except <poly*> -1:
+    if PY_TYPE_CHECK(p, MPolynomial_libsingular):
+        return (<MPolynomial_libsingular> p)._poly
+    else:
+        if PY_TYPE_CHECK(p, NCPolynomial_plural):
+            return (<NCPolynomial_plural> p)._poly
+    raise ValueError("not a singular polynomial wrapper")
+
+cdef ring* access_singular_ring(r) except <ring*> -1:
+    if PY_TYPE_CHECK(r, MPolynomialRing_libsingular):
+        return (<MPolynomialRing_libsingular> r )._ring
+    if PY_TYPE_CHECK(r, NCPolynomialRing_plural):
+        return (<NCPolynomialRing_plural> r )._ring
+    raise ValueError("not a singular polynomial ring wrapper")
+  
+cdef poly* copy_sage_polynomial_into_singular_poly(p):
+    return p_Copy(access_singular_poly(p), access_singular_ring(p.parent()))
+
 def all_vectors(s):
     """
     Checks if a sequence ``s`` consists of free module
@@ -269,12 +310,23 @@
         False
     """
     for p in s:
-        if not (isinstance(p, FreeModuleElement_generic_dense)\
-            and isinstance(p.parent().base_ring(), MPolynomialRing_libsingular)):
+        if not (PY_TYPE_CHECK(p, FreeModuleElement_generic_dense)\
+            and is_sage_wrapper_for_singular_ring(p.parent().base_ring())):
             return False
     return True
 
 
+cdef ring* sage_ring_to_singular_ring(ring) except <ring* > -1:
+    if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
+        return (<MPolynomialRing_libsingular>ring)._ring
+    elif PY_TYPE_CHECK(ring, NCPolynomialRing_plural):
+        return (<NCPolynomialRing_plural>ring)._ring
+    raise ValueError, "no singular ring found"
+
+
+
+
+
 
 cdef class Converter(SageObject):
     """
@@ -305,20 +357,16 @@
         cdef leftv *v
         self.args = NULL
         self._sage_ring = ring
-        if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
-            self._singular_ring = (<MPolynomialRing_libsingular>ring)._ring
-        elif PY_TYPE_CHECK(ring, NCPolynomialRing_plural):
-            self._singular_ring = (<NCPolynomialRing_plural>ring)._ring
+        if ring is not None:
+            self._singular_ring = sage_ring_to_singular_ring(ring)
         
         from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense
         from sage.matrix.matrix_integer_dense import Matrix_integer_dense
         for a in args:
-            if PY_TYPE_CHECK(a, MPolynomial_libsingular) or \
-                    PY_TYPE_CHECK(a, NCPolynomial_plural):
+            if is_polynomial(a):
                 v = self.append_polynomial(a)
 
-            elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular) or \
-                    PY_TYPE_CHECK(a, NCPolynomialRing_plural):
+            elif is_sage_wrapper_for_singular_ring(a):
                 v = self.append_ring(a)
 
             elif PY_TYPE_CHECK(a, MPolynomialIdeal) or \
@@ -341,9 +389,8 @@
                 v = self.append_resolution(a)
 
             elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\
-                and isinstance(
-                    a.parent().base_ring(),
-                    MPolynomialRing_libsingular):
+                and is_sage_wrapper_for_singular_ring(
+                    a.parent().base_ring()):
                 v = self.append_vector(a)
                 
             # as output ideals get converted to sequences
@@ -480,12 +527,9 @@
         ncols = mat.ncols
         nrows = mat.nrows
         result = Matrix(self._sage_ring, nrows, ncols)
-        #FIXME: NCPolynomial
-        cdef MPolynomial_libsingular p
         for i in xrange(nrows):
             for j in xrange(ncols):
-                p = MPolynomial_libsingular(self._sage_ring)
-                p._poly = mat.m[i*ncols+j]
+                p = new_sage_polynomial(self._sage_ring, mat.m[i*ncols+j])
                 mat.m[i*ncols+j]=NULL
                 result[i,j] = p
         return result
@@ -527,7 +571,8 @@
                 else:
                     previous = p_iter
                     p_iter = pNext(p_iter)
-            result.append(new_MP(self._sage_ring, first))
+            
+            result.append(new_sage_polynomial(self._sage_ring, first))
         return free_module(result)
           
     cdef object to_sage_module_element_sequence_destructive( self, ideal *i):
@@ -544,7 +589,7 @@
         #cdef MPolynomialRing_libsingular sage_ring = self._ring
         cdef int j
         cdef int rank=i.rank
-        free_module = self._sage_ring**rank       
+        free_module = self._sage_ring ** rank       
         l = []
 
         for j from 0 <= j < IDELEMS(i):
@@ -578,10 +623,8 @@
         Append the polynomial ``p`` to the list.
         """
         cdef poly* _p
-        if PY_TYPE_CHECK(p, MPolynomial_libsingular):
-            _p = p_Copy((<MPolynomial_libsingular>p)._poly, <ring*>((<MPolynomial_libsingular>p)._parent)._ring)
-        elif PY_TYPE_CHECK(p, NCPolynomial_plural):
-            _p = p_Copy((<NCPolynomial_plural>p)._poly, <ring*>((<NCPolynomial_plural>p)._parent)._ring)
+        _p = copy_sage_polynomial_into_singular_poly(p)
+                
         return self._append(_p, POLY_CMD)
 
     cdef leftv *append_ideal(self,  i) except NULL:
@@ -617,12 +660,11 @@
         cdef number *_n =  sa2si(n, self._singular_ring)
         return self._append(<void *>_n, NUMBER_CMD)
 
-    cdef leftv *append_ring(self, MPolynomialRing_libsingular r) except NULL:
+    cdef leftv *append_ring(self, r) except NULL:
         """
         Append the ring ``r`` to the list.
         """
-        #FIXME
-        cdef ring *_r =  <ring*> r._ring
+        cdef ring *_r =  access_singular_ring(r)
         _r.ref+=1
         return self._append(<void *>_r, RING_CMD)
 
@@ -1078,7 +1120,7 @@
 
         return prefix + get_docstring(self._name)
 
-    cdef MPolynomialRing_libsingular common_ring(self, tuple args, ring=None):
+    cdef common_ring(self, tuple args, ring=None):
         """
         Return the common ring for the argument list ``args``.
 
@@ -1099,13 +1141,13 @@
             if PY_TYPE_CHECK(a, MPolynomialIdeal) or \
                     PY_TYPE_CHECK(a, NCPolynomialIdeal):
                 ring2 = a.ring()
-            elif PY_TYPE_CHECK(a, MPolynomial_libsingular) or \
-                    PY_TYPE_CHECK(a, NCPolynomial_plural):
+            elif is_polynomial(a):
                 ring2 = a.parent()
-            elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular) or \
-                    PY_TYPE_CHECK(a, NCPolynomialRing_plural):
+            elif is_sage_wrapper_for_singular_ring(a):
                 ring2 = a
-            elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long) or PY_TYPE_CHECK(a, basestring):
+            elif PY_TYPE_CHECK(a, int) or\
+                PY_TYPE_CHECK(a, long) or\
+                PY_TYPE_CHECK(a, basestring):
                 continue
             elif PY_TYPE_CHECK(a, Matrix_integer_dense):
                 continue
@@ -1118,9 +1160,8 @@
             elif PY_TYPE_CHECK(a, Resolution):
                 ring2 = (<Resolution> a).base_ring
             elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\
-                and PY_TYPE_CHECK(
-                    a.parent().base_ring(),
-                     MPolynomialRing_libsingular):
+                and is_sage_wrapper_for_singular_ring(
+                    a.parent().base_ring()):
                 ring2 = a.parent().base_ring()
             elif ring is not None:
                 a.parent() is ring
@@ -1132,7 +1173,7 @@
                 raise ValueError("Rings do not match up.")
         if ring is None:
             raise ValueError("Could not detect ring.")
-        return <MPolynomialRing_libsingular>ring
+        return ring
 
     def __reduce__(self):
         """
@@ -1168,7 +1209,7 @@
     global errorreported
     
     cdef ring *si_ring
-    if isinstance(R, MPolynomialRing_libsingular):
+    if PY_TYPE_CHECK(R, MPolynomialRing_libsingular):
         si_ring = (<MPolynomialRing_libsingular>R)._ring
     else:
         si_ring = (<NCPolynomialRing_plural>R)._ring
@@ -1399,8 +1440,33 @@
         <Resolution>
         sage: singular_list(resolution)
         [[(-2*y, 2, y + 1, 0), (0, -2, x - 1, 0), (x*y - y, -y + 1, 1, -y), (x^2 + 1, -x - 1, -1, -x)], [(-x - 1, y - 1, 2*x, -2*y)], [(0)]]
-
-        
+        sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
+        sage: from sage.matrix.constructor  import Matrix
+        sage: c=Matrix(2)
+        sage: c[0,1]=-1
+        sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2))
+        sage: (x,y)=[P.gen(i) for i in xrange(2)]
+        sage: I= Sequence([x*y,x+y], check=False, immutable=True)#P.ideal(x*y,x+y)
+        sage: twostd = singular_function("twostd")
+        sage: twostd(I)
+        [x + y, y^2]
+        sage: M=syz(I)
+        doctest...
+        sage: M
+        [(x + y, x*y)]
+        sage: syz(M, ring=P)
+        [(0)]
+        sage: mres(I, 0)
+        <Resolution>
+        sage: M=P**3
+        sage: v=M((100*x,5*y,10*y*x*y))
+        sage: leadcoef(v)
+        -10
+        sage: v = M([x+y,x*y+y**3,x])
+        sage: lead(v)
+        (0, y^3)
+        sage: jet(v, 2)
+        (x + y, x*y, x)
     """
 
     cdef SingularFunction fnc
diff -r 54342f65c59c sage/modules/free_module.py
--- a/sage/modules/free_module.py	Thu Jul 15 11:38:43 2010 +0200
+++ b/sage/modules/free_module.py	Thu Jul 15 23:00:43 2010 +0200
@@ -182,6 +182,8 @@
 from sage.structure.parent_gens import ParentWithGens
 from sage.misc.cachefunc import cached_method
 
+from warnings import warn
+
 ###############################################################################
 #
 # Constructor functions
@@ -345,8 +347,21 @@
         if not isinstance(sparse,bool):
             raise TypeError, "Argument sparse (= %s) must be True or False" % sparse
 
+
+        # We should have two sided, left sided and right sided ideals,
+        # but that's another story ....
+        #
         if not base_ring.is_commutative():
-            raise TypeError, "The base_ring must be a commutative ring."
+            
+            warn("""You are constructing a free module
+             over a noncommutative ring. Sage does 
+             not have a concept of left/right
+             and both sided modules be careful. It's also
+             not guarantied that all multiplications
+             are done from the right side.""")
+            
+        #            raise TypeError, "The base_ring must be a commutative ring."
+
 
         if not sparse and isinstance(base_ring,sage.rings.real_double.RealDoubleField_class):
             return RealDoubleVectorSpace_class(rank)
@@ -558,8 +573,10 @@
             Category of modules with basis over Integer Ring
 
         """
-        if not isinstance(base_ring, commutative_ring.CommutativeRing):
-            raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring
+        if not base_ring.is_commutative():
+            warn("""You are constructing a free module over a noncommutative ring. Sage does not have a concept of left/right and both sided modules be careful. It's also not guarantied that all multiplications are done from the right side.""")
+            #raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring
+            
         rank = sage.rings.integer.Integer(rank)
         if rank < 0:
             raise ValueError, "rank (=%s) must be nonnegative"%rank
diff -r 54342f65c59c sage/rings/polynomial/plural.pyx
--- a/sage/rings/polynomial/plural.pyx	Thu Jul 15 11:38:43 2010 +0200
+++ b/sage/rings/polynomial/plural.pyx	Thu Jul 15 23:00:43 2010 +0200
@@ -13,7 +13,7 @@
 from sage.libs.singular.polynomial cimport singular_polynomial_deg, singular_polynomial_str_with_changed_varnames, singular_polynomial_latex, singular_polynomial_str, singular_polynomial_div_coeff
 
 from sage.libs.singular.singular cimport si2sa, sa2si, overflow_check
-
+from sage.rings.integer_ring import ZZ
 from term_order import TermOrder
 
 cdef class NCPolynomialRing_plural(Ring):
@@ -45,16 +45,55 @@
 
         self.__ngens = n
         ParentWithGens.__init__(self, base_ring, names)
+        self._populate_coercion_lists_()
+        
         #MPolynomialRing_generic.__init__(self, base_ring, n, names, order)
         #self._has_singular = True
         assert(n == len(self._names))
         
         self._one_element = new_NCP(self,p_ISet(1, self._ring))
         self._zero_element = new_NCP(self,NULL)
+    
+    
+    def _element_constructor_(self, x):
+       """
+       Make sure x is a valid member of self, and return the constructed element. 
+       """
+       if x==0:
+           return self._zero_element
+       raise NotImplementedError("not able to constructor "+repr(x))
+        
+    def _coerce_map_from_(self, S):
+       """
+       The only things that coerce into this ring are:
+           - the integer ring
+           - other localizations away from fewer primes
+       """
+       if S is ZZ:
+           return True
+       
+    def __pow__(self, n, _):
+        """
+        Return the free module of rank `n` over this ring.
 
+        EXAMPLES::
+
+        """
+        import sage.modules.all 
+        return sage.modules.all.FreeModule(self, n)
+    
+    
+    
     def term_order(self):
         return self.__term_order
 
+
+    def is_commutative(self):
+        return False
+    
+    def is_field(self):
+        return False
+    
     def _repr_(self):
         """
         EXAMPLE:
