+Libsolv\(cqs language bindings offer an abstract, object orientated interface to the library\&. The supported languages are currently perl, python, and ruby\&. All example code (except in the specifics sections, of course) lists first the \(lqC\-ish\(rq interface, then the syntax for perl, python, and ruby (in that order)\&.
+.SH "PERL SPECIFICS"
+.sp
+Libsolv\(cqs perl bindings can be loaded with the following statement:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBuse solv\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Objects are either created by calling the new() method on a class or they are returned by calling methods on other objects\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+my \fI$pool\fR \fB= solv::Pool\->new()\fR;
+my \fI$repo\fR \fB=\fR \fI$pool\fR\fB\->add_repo("my_first_repo")\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Swig encapsulates all objects as tied hashes, thus the attributes can be accessed by treating the object as standard hash reference:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fI$pool\fR\fB\->{appdata} = 42\fR;
+\fBprintf "appdata is %d\en",\fR \fI$pool\fR\fB\->{appdata}\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+A special exception to this are iterator objects, they are encapsulated as tied arrays so that it is possible to iterate with a for() statement:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+my \fI$iter\fR \fB=\fR \fI$pool\fR\fB\->solvables_iter()\fR;
+\fBfor my\fR \fI$solvable\fR \fB(\fR\fI@$iter\fR\fB) { \&.\&.\&. }\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+As a downside of this approach, iterator objects cannot have attributes\&.
+.sp
+If an array needs to be passed to a method it is usually done by reference, if a method returns an array it returns it on the stack:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+my \fI@problems\fR \fB=\fR \fI$solver\fR\fB\->solve(\e\fR\fI@jobs\fR\fB)\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Due to a bug in swig, stringification does not work for libsolv\(cqs objects\&. Instead, you have to call the object\(cqs str() method\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBprint\fR \fI$dep\fR\fB\->str() \&. "\e\fR\fIn\fR\fB"\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Swig implements all constants as numeric variables (instead of the more natural constant subs), so don\(cqt forget the leading \(lq$\(rq when accessing a constant\&. Also do not forget to prepend the namespace of the constant:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fI$pool\fR\fB\->set_flag($solv::Pool::POOL_FLAG_OBSOLETEUSESCOLORS, 1)\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "PYTHON SPECIFICS"
+.sp
+The python bindings can be loaded with:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBimport solv\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Objects are either created by calling the constructor method for a class or they are returned by calling methods on other objects\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIpool\fR \fB= solv\&.Pool()\fR
+\fIrepo\fR \fB=\fR \fIpool\fR\fB\&.add_repo("my_first_repo")\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Attributes can be accessed as usual:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIpool\fR\fB\&.appdata = 42\fR
+\fBprint "appdata is %d" % (\fR\fIpool\fR\fB\&.appdata)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Iterators also work as expected:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBfor\fR \fIsolvable\fR \fBin\fR \fIpool\fR\fB\&.solvables_iter():\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Arrays are passed and returned as list objects:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIjobs\fR \fB= []\fR
+\fIproblems\fR \fB=\fR \fIsolver\fR\fB\&.solve(\fR\fIjobs\fR\fB)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The bindings define stringification for many classes, some also have a \fIrepr\fR method to ease debugging\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBprint\fR \fIdep\fR
+\fBprint repr(\fR\fIrepo\fR\fB)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Constants are attributes of the classes:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIpool\fR\fB\&.set_flag(solv\&.Pool\&.POOL_FLAG_OBSOLETEUSESCOLORS, 1)\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "RUBY SPECIFICS"
+.sp
+The ruby bindings can be loaded with:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBrequire \*(Aqsolv\*(Aq\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Objects are either created by calling the new method on a class or they are returned by calling methods on other objects\&. Note that all classes start with an uppercase letter in ruby, so the class is called \(lqSolv\(rq\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIpool\fR \fB= Solv::Pool\&.new\fR
+\fIrepo\fR \fB=\fR \fIpool\fR\fB\&.add_repo("my_first_repo")\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Attributes can be accessed as usual:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIpool\fR\fB\&.appdata = 42\fR
+\fBputs "appdata is #{\fR\fIpool\fR\fB\&.appdata}"\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Iterators also work as expected:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBfor\fR \fIsolvable\fR \fBin\fR \fIpool\fR\fB\&.solvables_iter() do \&.\&.\&.\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Arrays are passed and returned as array objects:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIjobs\fR \fB= []\fR
+\fIproblems\fR \fB=\fR \fIsolver\fR\fB\&.solve(\fR\fIjobs\fR\fB)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Most classes define a to_s method, so objects can be easily stringified\&. Many also define an inspect() method\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBputs\fR \fIdep\fR
+\fBputs\fR \fIrepo\fR\fB\&.inspect\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Constants live in the namespace of the class they belong to:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIpool\fR\fB\&.set_flag(Solv::Pool::POOL_FLAG_OBSOLETEUSESCOLORS, 1)\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Note that boolean methods have an added trailing \(lq?\(rq, to be consistent with other ruby modules:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBputs "empty" if\fR \fIrepo\fR\fB\&.isempty?\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SH "TCL SPECIFICS"
+.sp
+Libsolv\(cqs tcl bindings can be loaded with the following statement:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBpackage require solv\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Objects are either created by calling class name prefixed with \(lqnew_\(rq, or they are returned by calling methods on other objects\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBset pool [solv::new_Pool]\fR
+\fBset repo [\fR\fI$pool\fR \fBadd_repo "my_first_repo"]\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Swig provides a \(lqcget\(rq method to read object attributes, and a \(lqconfigure\(rq method to write them:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fI$pool\fR \fBconfigure \-appdata 42\fR
+\fBputs "appdata is [\fR\fI$pool\fR \fBcget \-appdata]"\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The tcl bindings provide a little helper to work with iterators in a foreach style:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBset iter [\fR\fI$pool\fR \fBsolvables_iter]\fR
+\fBsolv::iter s\fR \fI$iter\fR \fB{ \&.\&.\&. }\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+libsolv\(cqs arrays are mapped to tcl\(cqs lists:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBset jobs [list\fR \fI$job1 $job2\fR\fB]\fR
+\fBset problems [\fR\fI$solver\fR \fBsolve\fR \fI$jobs\fR\fB]\fR
+\fBputs "We have [llength\fR \fI$problems\fR\fB] problems\&.\&.\&."\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Stringification is done by calling the object\(cqs \(lqstr\(rq method\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBputs [\fR\fI$dep\fR \fBstr]\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+There is one exception: you have to use \(lqstringify\(rq for Datamatch objects, as swig reports a clash with the \(lqstr\(rq attribute\&. Some objects also support a \(lq==\(rq method for equality tests, and a \(lq!=\(rq method\&.
+.sp
+Swig implements all constants as numeric variables, constants belonging to a libsolv class are prefixed with the class name:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fI$pool\fR \fBset_flag\fR \fI$solv::Pool_POOL_FLAG_OBSOLETEUSESCOLORS\fR \fB1\fR
+\fBputs [\fR\fI$solvable\fR \fBlookup_str\fR \fI$solv::SOLVABLE_SUMMARY\fR\fB]\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SH "THE SOLV CLASS"
+.sp
+This is the main namespace of the library, you cannot create objects of this type but it contains some useful constants\&.
+.SS "CONSTANTS"
+.sp
+Relational flag constants, the first three can be or\-ed together
+.PP
+\fBREL_LT\fR
+.RS 4
+the \(lqless than\(rq bit
+.RE
+.PP
+\fBREL_EQ\fR
+.RS 4
+the \(lqequals to\(rq bit
+.RE
+.PP
+\fBREL_GT\fR
+.RS 4
+the \(lqgreater than\(rq bit
+.RE
+.PP
+\fBREL_ARCH\fR
+.RS 4
+used for relations that describe an extra architecture filter, the version part of the relation is interpreted as architecture\&.
+.RE
+.sp
+Special Solvable Ids
+.PP
+\fBSOLVID_META\fR
+.RS 4
+Access the meta section of a repository or repodata area\&. This is like an extra Solvable that has the Id SOLVID_META\&.
+.RE
+.PP
+\fBSOLVID_POS\fR
+.RS 4
+Use the data position stored inside of the pool instead of accessing some solvable by Id\&. The bindings have the Datapos objects as an abstraction mechanism, so you do not need this constant\&.
+.RE
+.sp
+Constant string Ids
+.PP
+\fBID_NULL\fR
+.RS 4
+Always zero
+.RE
+.PP
+\fBID_EMPTY\fR
+.RS 4
+Always one, describes the empty string
+.RE
+.PP
+\fBSOLVABLE_NAME\fR
+.RS 4
+The keyname Id of the name of the solvable\&.
+.RE
+.PP
+\fB\&...\fR
+.RS 4
+see the libsolv\-constantids manpage for a list of fixed Ids\&.
+.RE
+.SH "THE POOL CLASS"