PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/opt/cpanel/ea-php81/root/usr/share/pear/PEAR/
Upload File :
Current File : //opt/cpanel/ea-php81/root/usr/share/pear/PEAR/Dependency2.php
<?php
/**
 * PEAR_Dependency2, advanced dependency validation
 *
 * PHP versions 4 and 5
 *
 * @category   pear
 * @package    PEAR
 * @author     Greg Beaver <cellog@php.net>
 * @copyright  1997-2009 The Authors
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @link       http://pear.php.net/package/PEAR
 * @since      File available since Release 1.4.0a1
 */

/**
 * Required for the PEAR_VALIDATE_* constants
 */
require_once 'PEAR/Validate.php';

/**
 * Dependency check for PEAR packages
 *
 * This class handles both version 1.0 and 2.0 dependencies
 * WARNING: *any* changes to this class must be duplicated in the
 * test_PEAR_Dependency2 class found in tests/PEAR_Dependency2/setup.php.inc,
 * or unit tests will not actually validate the changes
 * @category   pear
 * @package    PEAR
 * @author     Greg Beaver <cellog@php.net>
 * @copyright  1997-2009 The Authors
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @version    Release: 1.10.16
 * @link       http://pear.php.net/package/PEAR
 * @since      Class available since Release 1.4.0a1
 */
class PEAR_Dependency2
{
    /**
     * One of the PEAR_VALIDATE_* states
     * @see PEAR_VALIDATE_NORMAL
     * @var integer
     */
    var $_state;

    /**
     * Command-line options to install/upgrade/uninstall commands
     * @param array
     */
    var $_options;

    /**
     * @var OS_Guess
     */
    var $_os;

    /**
     * @var PEAR_Registry
     */
    var $_registry;

    /**
     * @var PEAR_Config
     */
    var $_config;

    /**
     * @var PEAR_DependencyDB
     */
    var $_dependencydb;

    /**
     * Output of PEAR_Registry::parsedPackageName()
     * @var array
     */
    var $_currentPackage;

    /**
     * @param PEAR_Config
     * @param array installation options
     * @param array format of PEAR_Registry::parsedPackageName()
     * @param int installation state (one of PEAR_VALIDATE_*)
     */
    function __construct(&$config, $installoptions, $package,
                              $state = PEAR_VALIDATE_INSTALLING)
    {
        $this->_config = &$config;
        if (!class_exists('PEAR_DependencyDB')) {
            require_once 'PEAR/DependencyDB.php';
        }

        if (isset($installoptions['packagingroot'])) {
            // make sure depdb is in the right location
            $config->setInstallRoot($installoptions['packagingroot']);
        }

        $this->_registry = &$config->getRegistry();
        $this->_dependencydb = &PEAR_DependencyDB::singleton($config);
        if (isset($installoptions['packagingroot'])) {
            $config->setInstallRoot(false);
        }

        $this->_options = $installoptions;
        $this->_state = $state;
        if (!class_exists('OS_Guess')) {
            require_once 'OS/Guess.php';
        }

        $this->_os = new OS_Guess;
        $this->_currentPackage = $package;
    }

    static function _getExtraString($dep)
    {
        $extra = ' (';
        if (isset($dep['uri'])) {
            return '';
        }

        if (isset($dep['recommended'])) {
            $extra .= 'recommended version ' . $dep['recommended'];
        } else {
            if (isset($dep['min'])) {
                $extra .= 'version >= ' . $dep['min'];
            }

            if (isset($dep['max'])) {
                if ($extra != ' (') {
                    $extra .= ', ';
                }
                $extra .= 'version <= ' . $dep['max'];
            }

            if (isset($dep['exclude'])) {
                if (!is_array($dep['exclude'])) {
                    $dep['exclude'] = array($dep['exclude']);
                }

                if ($extra != ' (') {
                    $extra .= ', ';
                }

                $extra .= 'excluded versions: ';
                foreach ($dep['exclude'] as $i => $exclude) {
                    if ($i) {
                        $extra .= ', ';
                    }
                    $extra .= $exclude;
                }
            }
        }

        $extra .= ')';
        if ($extra == ' ()') {
            $extra = '';
        }

        return $extra;
    }

    /**
     * This makes unit-testing a heck of a lot easier
     */
    function getPHP_OS()
    {
        return PHP_OS;
    }

    /**
     * This makes unit-testing a heck of a lot easier
     */
    function getsysname()
    {
        return $this->_os->getSysname();
    }

    /**
     * Specify a dependency on an OS.  Use arch for detailed os/processor information
     *
     * There are two generic OS dependencies that will be the most common, unix and windows.
     * Other options are linux, freebsd, darwin (OS X), sunos, irix, hpux, aix
     */
    function validateOsDependency($dep)
    {
        if ($this->_state != PEAR_VALIDATE_INSTALLING && $this->_state != PEAR_VALIDATE_DOWNLOADING) {
            return true;
        }

        if ($dep['name'] == '*') {
            return true;
        }

        $not = isset($dep['conflicts']) ? true : false;
        switch (strtolower($dep['name'])) {
            case 'windows' :
                if ($not) {
                    if (strtolower(substr($this->getPHP_OS(), 0, 3)) == 'win') {
                        if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                            return $this->raiseError("Cannot install %s on Windows");
                        }

                        return $this->warning("warning: Cannot install %s on Windows");
                    }
                } else {
                    if (strtolower(substr($this->getPHP_OS(), 0, 3)) != 'win') {
                        if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                            return $this->raiseError("Can only install %s on Windows");
                        }

                        return $this->warning("warning: Can only install %s on Windows");
                    }
                }
            break;
            case 'unix' :
                $unices = array('linux', 'freebsd', 'darwin', 'sunos', 'irix', 'hpux', 'aix');
                if ($not) {
                    if (in_array($this->getSysname(), $unices)) {
                        if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                            return $this->raiseError("Cannot install %s on any Unix system");
                        }

                        return $this->warning( "warning: Cannot install %s on any Unix system");
                    }
                } else {
                    if (!in_array($this->getSysname(), $unices)) {
                        if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                            return $this->raiseError("Can only install %s on a Unix system");
                        }

                        return $this->warning("warning: Can only install %s on a Unix system");
                    }
                }
            break;
            default :
                if ($not) {
                    if (strtolower($dep['name']) == strtolower($this->getSysname())) {
                        if (!isset($this->_options['nodeps']) &&
                              !isset($this->_options['force'])) {
                            return $this->raiseError('Cannot install %s on ' . $dep['name'] .
                                ' operating system');
                        }

                        return $this->warning('warning: Cannot install %s on ' .
                            $dep['name'] . ' operating system');
                    }
                } else {
                    if (strtolower($dep['name']) != strtolower($this->getSysname())) {
                        if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                            return $this->raiseError('Cannot install %s on ' .
                                $this->getSysname() .
                                ' operating system, can only install on ' . $dep['name']);
                        }

                        return $this->warning('warning: Cannot install %s on ' .
                            $this->getSysname() .
                            ' operating system, can only install on ' . $dep['name']);
                    }
                }
        }
        return true;
    }

    /**
     * This makes unit-testing a heck of a lot easier
     */
    function matchSignature($pattern)
    {
        return $this->_os->matchSignature($pattern);
    }

    /**
     * Specify a complex dependency on an OS/processor/kernel version,
     * Use OS for simple operating system dependency.
     *
     * This is the only dependency that accepts an eregable pattern.  The pattern
     * will be matched against the php_uname() output parsed by OS_Guess
     */
    function validateArchDependency($dep)
    {
        if ($this->_state != PEAR_VALIDATE_INSTALLING) {
            return true;
        }

        $not = isset($dep['conflicts']) ? true : false;
        if (!$this->matchSignature($dep['pattern'])) {
            if (!$not) {
                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                    return $this->raiseError('%s Architecture dependency failed, does not ' .
                        'match "' . $dep['pattern'] . '"');
                }

                return $this->warning('warning: %s Architecture dependency failed, does ' .
                    'not match "' . $dep['pattern'] . '"');
            }

            return true;
        }

        if ($not) {
            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                return $this->raiseError('%s Architecture dependency failed, required "' .
                    $dep['pattern'] . '"');
            }

            return $this->warning('warning: %s Architecture dependency failed, ' .
                'required "' . $dep['pattern'] . '"');
        }

        return true;
    }

    /**
     * This makes unit-testing a heck of a lot easier
     */
    function extension_loaded($name)
    {
        return extension_loaded($name);
    }

    /**
     * This makes unit-testing a heck of a lot easier
     */
    function phpversion($name = null)
    {
        if ($name !== null) {
            return phpversion($name);
        }

        return phpversion();
    }

    function validateExtensionDependency($dep, $required = true)
    {
        if ($this->_state != PEAR_VALIDATE_INSTALLING &&
              $this->_state != PEAR_VALIDATE_DOWNLOADING) {
            return true;
        }

        $loaded = $this->extension_loaded($dep['name']);
        $extra  = self::_getExtraString($dep);
        if (isset($dep['exclude'])) {
            if (!is_array($dep['exclude'])) {
                $dep['exclude'] = array($dep['exclude']);
            }
        }

        if (!isset($dep['min']) && !isset($dep['max']) &&
            !isset($dep['recommended']) && !isset($dep['exclude'])
        ) {
            if ($loaded) {
                if (isset($dep['conflicts'])) {
                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                        return $this->raiseError('%s conflicts with PHP extension "' .
                            $dep['name'] . '"' . $extra);
                    }

                    return $this->warning('warning: %s conflicts with PHP extension "' .
                        $dep['name'] . '"' . $extra);
                }

                return true;
            }

            if (isset($dep['conflicts'])) {
                return true;
            }

            if ($required) {
                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                    return $this->raiseError('%s requires PHP extension "' .
                        $dep['name'] . '"' . $extra);
                }

                return $this->warning('warning: %s requires PHP extension "' .
                    $dep['name'] . '"' . $extra);
            }

            return $this->warning('%s can optionally use PHP extension "' .
                $dep['name'] . '"' . $extra);
        }

        if (!$loaded) {
            if (isset($dep['conflicts'])) {
                return true;
            }

            if (!$required) {
                return $this->warning('%s can optionally use PHP extension "' .
                    $dep['name'] . '"' . $extra);
            }

            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                return $this->raiseError('%s requires PHP extension "' . $dep['name'] .
                    '"' . $extra);
            }

            return $this->warning('warning: %s requires PHP extension "' . $dep['name'] .
                    '"' . $extra);
        }

        $version = (string) $this->phpversion($dep['name']);
        if (empty($version)) {
            $version = '0';
        }

        $fail = false;
        if (isset($dep['min']) && !version_compare($version, $dep['min'], '>=')) {
            $fail = true;
        }

        if (isset($dep['max']) && !version_compare($version, $dep['max'], '<=')) {
            $fail = true;
        }

        if ($fail && !isset($dep['conflicts'])) {
            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                return $this->raiseError('%s requires PHP extension "' . $dep['name'] .
                    '"' . $extra . ', installed version is ' . $version);
            }

            return $this->warning('warning: %s requires PHP extension "' . $dep['name'] .
                '"' . $extra . ', installed version is ' . $version);
        } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && isset($dep['conflicts'])) {
            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                return $this->raiseError('%s conflicts with PHP extension "' .
                    $dep['name'] . '"' . $extra . ', installed version is ' . $version);
            }

            return $this->warning('warning: %s conflicts with PHP extension "' .
                $dep['name'] . '"' . $extra . ', installed version is ' . $version);
        }

        if (isset($dep['exclude'])) {
            foreach ($dep['exclude'] as $exclude) {
                if (version_compare($version, $exclude, '==')) {
                    if (isset($dep['conflicts'])) {
                        continue;
                    }

                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                        return $this->raiseError('%s is not compatible with PHP extension "' .
                            $dep['name'] . '" version ' .
                            $exclude);
                    }

                    return $this->warning('warning: %s is not compatible with PHP extension "' .
                        $dep['name'] . '" version ' .
                        $exclude);
                } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) {
                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                        return $this->raiseError('%s conflicts with PHP extension "' .
                            $dep['name'] . '"' . $extra . ', installed version is ' . $version);
                    }

                    return $this->warning('warning: %s conflicts with PHP extension "' .
                        $dep['name'] . '"' . $extra . ', installed version is ' . $version);
                }
            }
        }

        if (isset($dep['recommended'])) {
            if (version_compare($version, $dep['recommended'], '==')) {
                return true;
            }

            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                return $this->raiseError('%s dependency: PHP extension ' . $dep['name'] .
                    ' version "' . $version . '"' .
                    ' is not the recommended version "' . $dep['recommended'] .
                    '", but may be compatible, use --force to install');
            }

            return $this->warning('warning: %s dependency: PHP extension ' .
                $dep['name'] . ' version "' . $version . '"' .
                ' is not the recommended version "' . $dep['recommended'].'"');
        }

        return true;
    }

    function validatePhpDependency($dep)
    {
        if ($this->_state != PEAR_VALIDATE_INSTALLING &&
              $this->_state != PEAR_VALIDATE_DOWNLOADING) {
            return true;
        }

        $version = $this->phpversion();
        $extra   = self::_getExtraString($dep);
        if (isset($dep['exclude'])) {
            if (!is_array($dep['exclude'])) {
                $dep['exclude'] = array($dep['exclude']);
            }
        }

        if (isset($dep['min'])) {
            if (!version_compare($version, $dep['min'], '>=')) {
                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                    return $this->raiseError('%s requires PHP' .
                        $extra . ', installed version is ' . $version);
                }

                return $this->warning('warning: %s requires PHP' .
                    $extra . ', installed version is ' . $version);
            }
        }

        if (isset($dep['max'])) {
            if (!version_compare($version, $dep['max'], '<=')) {
                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                    return $this->raiseError('%s requires PHP' .
                        $extra . ', installed version is ' . $version);
                }

                return $this->warning('warning: %s requires PHP' .
                    $extra . ', installed version is ' . $version);
            }
        }

        if (isset($dep['exclude'])) {
            foreach ($dep['exclude'] as $exclude) {
                if (version_compare($version, $exclude, '==')) {
                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                        return $this->raiseError('%s is not compatible with PHP version ' .
                            $exclude);
                    }

                    return $this->warning(
                        'warning: %s is not compatible with PHP version ' .
                        $exclude);
                }
            }
        }

        return true;
    }

    /**
     * This makes unit-testing a heck of a lot easier
     */
    function getPEARVersion()
    {
        return '1.10.16';
    }

    function validatePearinstallerDependency($dep)
    {
        $pearversion = $this->getPEARVersion();
        $extra = self::_getExtraString($dep);
        if (isset($dep['exclude'])) {
            if (!is_array($dep['exclude'])) {
                $dep['exclude'] = array($dep['exclude']);
            }
        }

        if (version_compare($pearversion, $dep['min'], '<')) {
            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                return $this->raiseError('%s requires PEAR Installer' . $extra .
                    ', installed version is ' . $pearversion);
            }

            return $this->warning('warning: %s requires PEAR Installer' . $extra .
                ', installed version is ' . $pearversion);
        }

        if (isset($dep['max'])) {
            if (version_compare($pearversion, $dep['max'], '>')) {
                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                    return $this->raiseError('%s requires PEAR Installer' . $extra .
                        ', installed version is ' . $pearversion);
                }

                return $this->warning('warning: %s requires PEAR Installer' . $extra .
                    ', installed version is ' . $pearversion);
            }
        }

        if (isset($dep['exclude'])) {
            if (!isset($dep['exclude'][0])) {
                $dep['exclude'] = array($dep['exclude']);
            }

            foreach ($dep['exclude'] as $exclude) {
                if (version_compare($exclude, $pearversion, '==')) {
                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                        return $this->raiseError('%s is not compatible with PEAR Installer ' .
                            'version ' . $exclude);
                    }

                    return $this->warning('warning: %s is not compatible with PEAR ' .
                        'Installer version ' . $exclude);
                }
            }
        }

        return true;
    }

    function validateSubpackageDependency($dep, $required, $params)
    {
        return $this->validatePackageDependency($dep, $required, $params);
    }

    /**
     * @param array dependency information (2.0 format)
     * @param boolean whether this is a required dependency
     * @param array a list of downloaded packages to be installed, if any
     * @param boolean if true, then deps on pear.php.net that fail will also check
     *                against pecl.php.net packages to accommodate extensions that have
     *                moved to pecl.php.net from pear.php.net
     */
    function validatePackageDependency($dep, $required, $params, $depv1 = false)
    {
        if ($this->_state != PEAR_VALIDATE_INSTALLING &&
              $this->_state != PEAR_VALIDATE_DOWNLOADING) {
            return true;
        }

        if (isset($dep['providesextension'])) {
            if ($this->extension_loaded($dep['providesextension'])) {
                $save = $dep;
                $subdep = $dep;
                $subdep['name'] = $subdep['providesextension'];
                PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
                $ret = $this->validateExtensionDependency($subdep, $required);
                PEAR::popErrorHandling();
                if (!PEAR::isError($ret)) {
                    return true;
                }
            }
        }

        if ($this->_state == PEAR_VALIDATE_INSTALLING) {
            return $this->_validatePackageInstall($dep, $required, $depv1);
        }

        if ($this->_state == PEAR_VALIDATE_DOWNLOADING) {
            return $this->_validatePackageDownload($dep, $required, $params, $depv1);
        }
    }

    function _validatePackageDownload($dep, $required, $params, $depv1 = false)
    {
        $dep['package'] = $dep['name'];
        if (isset($dep['uri'])) {
            $dep['channel'] = '__uri';
        }

        $depname = $this->_registry->parsedPackageNameToString($dep, true);
        $found = false;
        foreach ($params as $param) {
            if ($param->isEqual(
                  array('package' => $dep['name'],
                        'channel' => $dep['channel']))) {
                $found = true;
                break;
            }

            if ($depv1 && $dep['channel'] == 'pear.php.net') {
                if ($param->isEqual(
                  array('package' => $dep['name'],
                        'channel' => 'pecl.php.net'))) {
                    $found = true;
                    break;
                }
            }
        }

        if (!$found && isset($dep['providesextension'])) {
            foreach ($params as $param) {
                if ($param->isExtension($dep['providesextension'])) {
                    $found = true;
                    break;
                }
            }
        }

        if ($found) {
            $version = $param->getVersion();
            $installed = false;
            $downloaded = true;
        } else {
            if ($this->_registry->packageExists($dep['name'], $dep['channel'])) {
                $installed = true;
                $downloaded = false;
                $version = $this->_registry->packageinfo($dep['name'], 'version',
                    $dep['channel']);
            } else {
                if ($dep['channel'] == 'pecl.php.net' && $this->_registry->packageExists($dep['name'],
                      'pear.php.net')) {
                    $installed = true;
                    $downloaded = false;
                    $version = $this->_registry->packageinfo($dep['name'], 'version',
                        'pear.php.net');
                } else {
                    $version = 'not installed or downloaded';
                    $installed = false;
                    $downloaded = false;
                }
            }
        }

        $extra = self::_getExtraString($dep);
        if (isset($dep['exclude']) && !is_array($dep['exclude'])) {
            $dep['exclude'] = array($dep['exclude']);
        }

        if (!isset($dep['min']) && !isset($dep['max']) &&
              !isset($dep['recommended']) && !isset($dep['exclude'])
        ) {
            if ($installed || $downloaded) {
                $installed = $installed ? 'installed' : 'downloaded';
                if (isset($dep['conflicts'])) {
                    $rest = '';
                    if ($version) {
                        $rest = ", $installed version is " . $version;
                    }

                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                        return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . $rest);
                    }

                    return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . $rest);
                }

                return true;
            }

            if (isset($dep['conflicts'])) {
                return true;
            }

            if ($required) {
                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                    return $this->raiseError('%s requires package "' . $depname . '"' . $extra);
                }

                return $this->warning('warning: %s requires package "' . $depname . '"' . $extra);
            }

            return $this->warning('%s can optionally use package "' . $depname . '"' . $extra);
        }

        if (!$installed && !$downloaded) {
            if (isset($dep['conflicts'])) {
                return true;
            }

            if ($required) {
                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                    return $this->raiseError('%s requires package "' . $depname . '"' . $extra);
                }

                return $this->warning('warning: %s requires package "' . $depname . '"' . $extra);
            }

            return $this->warning('%s can optionally use package "' . $depname . '"' . $extra);
        }

        $fail = false;
        if (isset($dep['min']) && version_compare($version, $dep['min'], '<')) {
            $fail = true;
        }

        if (isset($dep['max']) && version_compare($version, $dep['max'], '>')) {
            $fail = true;
        }

        if ($fail && !isset($dep['conflicts'])) {
            $installed = $installed ? 'installed' : 'downloaded';
            $dep['package'] = $dep['name'];
            $dep = $this->_registry->parsedPackageNameToString($dep, true);
            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                return $this->raiseError('%s requires package "' . $depname . '"' .
                    $extra . ", $installed version is " . $version);
            }

            return $this->warning('warning: %s requires package "' . $depname . '"' .
                $extra . ", $installed version is " . $version);
        } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail &&
              isset($dep['conflicts']) && !isset($dep['exclude'])) {
            $installed = $installed ? 'installed' : 'downloaded';
            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra .
                    ", $installed version is " . $version);
            }

            return $this->warning('warning: %s conflicts with package "' . $depname . '"' .
                $extra . ", $installed version is " . $version);
        }

        if (isset($dep['exclude'])) {
            $installed = $installed ? 'installed' : 'downloaded';
            foreach ($dep['exclude'] as $exclude) {
                if (version_compare($version, $exclude, '==') && !isset($dep['conflicts'])) {
                    if (!isset($this->_options['nodeps']) &&
                          !isset($this->_options['force'])
                    ) {
                        return $this->raiseError('%s is not compatible with ' .
                            $installed . ' package "' .
                            $depname . '" version ' .
                            $exclude);
                    }

                    return $this->warning('warning: %s is not compatible with ' .
                        $installed . ' package "' .
                        $depname . '" version ' .
                        $exclude);
                } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) {
                    $installed = $installed ? 'installed' : 'downloaded';
                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                        return $this->raiseError('%s conflicts with package "' . $depname . '"' .
                            $extra . ", $installed version is " . $version);
                    }

                    return $this->warning('warning: %s conflicts with package "' . $depname . '"' .
                        $extra . ", $installed version is " . $version);
                }
            }
        }

        if (isset($dep['recommended'])) {
            $installed = $installed ? 'installed' : 'downloaded';
            if (version_compare($version, $dep['recommended'], '==')) {
                return true;
            }

            if (!$found && $installed) {
                $param = $this->_registry->getPackage($dep['name'], $dep['channel']);
            }

            if ($param) {
                $found = false;
                foreach ($params as $parent) {
                    if ($parent->isEqual($this->_currentPackage)) {
                        $found = true;
                        break;
                    }
                }

                if ($found) {
                    if ($param->isCompatible($parent)) {
                        return true;
                    }
                } else { // this is for validPackage() calls
                    $parent = $this->_registry->getPackage($this->_currentPackage['package'],
                        $this->_currentPackage['channel']);
                    if ($parent !== null && $param->isCompatible($parent)) {
                        return true;
                    }
                }
            }

            if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) &&
                  !isset($this->_options['loose'])
            ) {
                return $this->raiseError('%s dependency package "' . $depname .
                    '" ' . $installed . ' version ' . $version .
                    ' is not the recommended version ' . $dep['recommended'] .
                    ', but may be compatible, use --force to install');
            }

            return $this->warning('warning: %s dependency package "' . $depname .
                '" ' . $installed . ' version ' . $version .
                ' is not the recommended version ' . $dep['recommended']);
        }

        return true;
    }

    function _validatePackageInstall($dep, $required, $depv1 = false)
    {
        return $this->_validatePackageDownload($dep, $required, array(), $depv1);
    }

    /**
     * Verify that uninstalling packages passed in to command line is OK.
     *
     * @param PEAR_Installer $dl
     * @return PEAR_Error|true
     */
    function validatePackageUninstall(&$dl)
    {
        if (PEAR::isError($this->_dependencydb)) {
            return $this->_dependencydb;
        }

        $params = array();
        // construct an array of "downloaded" packages to fool the package dependency checker
        // into using these to validate uninstalls of circular dependencies
        $downloaded = &$dl->getUninstallPackages();
        foreach ($downloaded as $i => $pf) {
            if (!class_exists('PEAR_Downloader_Package')) {
                require_once 'PEAR/Downloader/Package.php';
            }
            $dp = new PEAR_Downloader_Package($dl);
            $dp->setPackageFile($downloaded[$i]);
            $params[$i] = $dp;
        }

        // check cache
        $memyselfandI = strtolower($this->_currentPackage['channel']) . '/' .
            strtolower($this->_currentPackage['package']);
        if (isset($dl->___uninstall_package_cache)) {
            $badpackages = $dl->___uninstall_package_cache;
            if (isset($badpackages[$memyselfandI]['warnings'])) {
                foreach ($badpackages[$memyselfandI]['warnings'] as $warning) {
                    $dl->log(0, $warning[0]);
                }
            }

            if (isset($badpackages[$memyselfandI]['errors'])) {
                foreach ($badpackages[$memyselfandI]['errors'] as $error) {
                    if (is_array($error)) {
                        $dl->log(0, $error[0]);
                    } else {
                        $dl->log(0, $error->getMessage());
                    }
                }

                if (isset($this->_options['nodeps']) || isset($this->_options['force'])) {
                    return $this->warning(
                        'warning: %s should not be uninstalled, other installed packages depend ' .
                        'on this package');
                }

                return $this->raiseError(
                    '%s cannot be uninstalled, other installed packages depend on this package');
            }

            return true;
        }

        // first, list the immediate parents of each package to be uninstalled
        $perpackagelist = array();
        $allparents = array();
        foreach ($params as $i => $param) {
            $a = array(
                'channel' => strtolower($param->getChannel()),
                'package' => strtolower($param->getPackage())
            );

            $deps = $this->_dependencydb->getDependentPackages($a);
            if ($deps) {
                foreach ($deps as $d) {
                    $pardeps = $this->_dependencydb->getDependencies($d);
                    foreach ($pardeps as $dep) {
                        if (strtolower($dep['dep']['channel']) == $a['channel'] &&
                              strtolower($dep['dep']['name']) == $a['package']) {
                            if (!isset($perpackagelist[$a['channel'] . '/' . $a['package']])) {
                                $perpackagelist[$a['channel'] . '/' . $a['package']] = array();
                            }
                            $perpackagelist[$a['channel'] . '/' . $a['package']][]
                                = array($d['channel'] . '/' . $d['package'], $dep);
                            if (!isset($allparents[$d['channel'] . '/' . $d['package']])) {
                                $allparents[$d['channel'] . '/' . $d['package']] = array();
                            }
                            if (!isset($allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']])) {
                                $allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']] = array();
                            }
                            $allparents[$d['channel'] . '/' . $d['package']]
                                       [$a['channel'] . '/' . $a['package']][]
                                = array($d, $dep);
                        }
                    }
                }
            }
        }

        // next, remove any packages from the parents list that are not installed
        $remove = array();
        foreach ($allparents as $parent => $d1) {
            foreach ($d1 as $d) {
                if ($this->_registry->packageExists($d[0][0]['package'], $d[0][0]['channel'])) {
                    continue;
                }
                $remove[$parent] = true;
            }
        }

        // next remove any packages from the parents list that are not passed in for
        // uninstallation
        foreach ($allparents as $parent => $d1) {
            foreach ($d1 as $d) {
                foreach ($params as $param) {
                    if (strtolower($param->getChannel()) == $d[0][0]['channel'] &&
                          strtolower($param->getPackage()) == $d[0][0]['package']) {
                        // found it
                        continue 3;
                    }
                }
                $remove[$parent] = true;
            }
        }

        // remove all packages whose dependencies fail
        // save which ones failed for error reporting
        $badchildren = array();
        do {
            $fail = false;
            foreach ($remove as $package => $unused) {
                if (!isset($allparents[$package])) {
                    continue;
                }

                foreach ($allparents[$package] as $kid => $d1) {
                    foreach ($d1 as $depinfo) {
                        if ($depinfo[1]['type'] != 'optional') {
                            if (isset($badchildren[$kid])) {
                                continue;
                            }
                            $badchildren[$kid] = true;
                            $remove[$kid] = true;
                            $fail = true;
                            continue 2;
                        }
                    }
                }
                if ($fail) {
                    // start over, we removed some children
                    continue 2;
                }
            }
        } while ($fail);

        // next, construct the list of packages that can't be uninstalled
        $badpackages = array();
        $save = $this->_currentPackage;
        foreach ($perpackagelist as $package => $packagedeps) {
            foreach ($packagedeps as $parent) {
                if (!isset($remove[$parent[0]])) {
                    continue;
                }

                $packagename = $this->_registry->parsePackageName($parent[0]);
                $packagename['channel'] = $this->_registry->channelAlias($packagename['channel']);
                $pa = $this->_registry->getPackage($packagename['package'], $packagename['channel']);
                $packagename['package'] = $pa->getPackage();
                $this->_currentPackage = $packagename;
                // parent is not present in uninstall list, make sure we can actually
                // uninstall it (parent dep is optional)
                $parentname['channel'] = $this->_registry->channelAlias($parent[1]['dep']['channel']);
                $pa = $this->_registry->getPackage($parent[1]['dep']['name'], $parent[1]['dep']['channel']);
                $parentname['package'] = $pa->getPackage();
                $parent[1]['dep']['package'] = $parentname['package'];
                $parent[1]['dep']['channel'] = $parentname['channel'];
                if ($parent[1]['type'] == 'optional') {
                    $test = $this->_validatePackageUninstall($parent[1]['dep'], false, $dl);
                    if ($test !== true) {
                        $badpackages[$package]['warnings'][] = $test;
                    }
                } else {
                    $test = $this->_validatePackageUninstall($parent[1]['dep'], true, $dl);
                    if ($test !== true) {
                        $badpackages[$package]['errors'][] = $test;
                    }
                }
            }
        }

        $this->_currentPackage          = $save;
        $dl->___uninstall_package_cache = $badpackages;
        if (isset($badpackages[$memyselfandI])) {
            if (isset($badpackages[$memyselfandI]['warnings'])) {
                foreach ($badpackages[$memyselfandI]['warnings'] as $warning) {
                    $dl->log(0, $warning[0]);
                }
            }

            if (isset($badpackages[$memyselfandI]['errors'])) {
                foreach ($badpackages[$memyselfandI]['errors'] as $error) {
                    if (is_array($error)) {
                        $dl->log(0, $error[0]);
                    } else {
                        $dl->log(0, $error->getMessage());
                    }
                }

                if (isset($this->_options['nodeps']) || isset($this->_options['force'])) {
                    return $this->warning(
                        'warning: %s should not be uninstalled, other installed packages depend ' .
                        'on this package');
                }

                return $this->raiseError(
                    '%s cannot be uninstalled, other installed packages depend on this package');
            }
        }

        return true;
    }

    function _validatePackageUninstall($dep, $required, $dl)
    {
        $depname = $this->_registry->parsedPackageNameToString($dep, true);
        $version = $this->_registry->packageinfo($dep['package'], 'version', $dep['channel']);
        if (!$version) {
            return true;
        }

        $extra = self::_getExtraString($dep);
        if (isset($dep['exclude']) && !is_array($dep['exclude'])) {
            $dep['exclude'] = array($dep['exclude']);
        }

        if (isset($dep['conflicts'])) {
            return true; // uninstall OK - these packages conflict (probably installed with --force)
        }

        if (!isset($dep['min']) && !isset($dep['max'])) {
            if (!$required) {
                return $this->warning('"' . $depname . '" can be optionally used by ' .
                        'installed package %s' . $extra);
            }

            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
                return $this->raiseError('"' . $depname . '" is required by ' .
                    'installed package %s' . $extra);
            }

            return $this->warning('warning: "' . $depname . '" is required by ' .
                'installed package %s' . $extra);
        }

        $fail = false;
        if (isset($dep['min']) && version_compare($version, $dep['min'], '>=')) {
            $fail = true;
        }

        if (isset($dep['max']) && version_compare($version, $dep['max'], '<=')) {
            $fail = true;
        }

        // we re-use this variable, preserve the original value
        $saverequired = $required;
        if (!$required) {
            return $this->warning($depname . $extra . ' can be optionally used by installed package' .
                    ' "%s"');
        }

        if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
            return $this->raiseError($depname . $extra . ' is required by installed package' .
                ' "%s"');
        }

        return $this->raiseError('warning: ' . $depname . $extra .
            ' is required by installed package "%s"');
    }

    /**
     * validate a downloaded package against installed packages
     *
     * As of PEAR 1.4.3, this will only validate
     *
     * @param array|PEAR_Downloader_Package|PEAR_PackageFile_v1|PEAR_PackageFile_v2
     *              $pkg package identifier (either
     *                   array('package' => blah, 'channel' => blah) or an array with
     *                   index 'info' referencing an object)
     * @param PEAR_Downloader $dl
     * @param array $params full list of packages to install
     * @return true|PEAR_Error
     */
    function validatePackage($pkg, &$dl, $params = array())
    {
        if (is_array($pkg) && isset($pkg['info'])) {
            $deps = $this->_dependencydb->getDependentPackageDependencies($pkg['info']);
        } else {
            $deps = $this->_dependencydb->getDependentPackageDependencies($pkg);
        }

        $fail = false;
        if ($deps) {
            if (!class_exists('PEAR_Downloader_Package')) {
                require_once 'PEAR/Downloader/Package.php';
            }

            $dp = new PEAR_Downloader_Package($dl);
            if (is_object($pkg)) {
                $dp->setPackageFile($pkg);
            } else {
                $dp->setDownloadURL($pkg);
            }

            PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
            foreach ($deps as $channel => $info) {
                foreach ($info as $package => $ds) {
                    foreach ($params as $packd) {
                        if (strtolower($packd->getPackage()) == strtolower($package) &&
                              $packd->getChannel() == $channel) {
                            $dl->log(3, 'skipping installed package check of "' .
                                        $this->_registry->parsedPackageNameToString(
                                            array('channel' => $channel, 'package' => $package),
                                            true) .
                                        '", version "' . $packd->getVersion() . '" will be ' .
                                        'downloaded and installed');
                            continue 2; // jump to next package
                        }
                    }

                    foreach ($ds as $d) {
                        $checker = new PEAR_Dependency2($this->_config, $this->_options,
                            array('channel' => $channel, 'package' => $package), $this->_state);
                        $dep = $d['dep'];
                        $required = $d['type'] == 'required';
                        $ret = $checker->_validatePackageDownload($dep, $required, array(&$dp));
                        if (is_array($ret)) {
                            $dl->log(0, $ret[0]);
                        } elseif (PEAR::isError($ret)) {
                            $dl->log(0, $ret->getMessage());
                            $fail = true;
                        }
                    }
                }
            }
            PEAR::popErrorHandling();
        }

        if ($fail) {
            return $this->raiseError(
                '%s cannot be installed, conflicts with installed packages');
        }

        return true;
    }

    /**
     * validate a package.xml 1.0 dependency
     */
    function validateDependency1($dep, $params = array())
    {
        if (!isset($dep['optional'])) {
            $dep['optional'] = 'no';
        }

        list($newdep, $type) = self::normalizeDep($dep);
        if (!$newdep) {
            return $this->raiseError("Invalid Dependency");
        }

        if (method_exists($this, "validate{$type}Dependency")) {
            return $this->{"validate{$type}Dependency"}($newdep, $dep['optional'] == 'no',
                $params, true);
        }
    }

    /**
     * Convert a 1.0 dep into a 2.0 dep
     */
    static function normalizeDep($dep)
    {
        $types = array(
            'pkg' => 'Package',
            'ext' => 'Extension',
            'os' => 'Os',
            'php' => 'Php'
        );

        if (!isset($types[$dep['type']])) {
            return array(false, false);
        }

        $type = $types[$dep['type']];

        $newdep = array();
        switch ($type) {
            case 'Package' :
                $newdep['channel'] = 'pear.php.net';
            case 'Extension' :
            case 'Os' :
                $newdep['name'] = $dep['name'];
            break;
        }

        $dep['rel'] = PEAR_Dependency2::signOperator($dep['rel']);
        switch ($dep['rel']) {
            case 'has' :
                return array($newdep, $type);
            break;
            case 'not' :
                $newdep['conflicts'] = true;
            break;
            case '>=' :
            case '>' :
                $newdep['min'] = $dep['version'];
                if ($dep['rel'] == '>') {
                    $newdep['exclude'] = $dep['version'];
                }
            break;
            case '<=' :
            case '<' :
                $newdep['max'] = $dep['version'];
                if ($dep['rel'] == '<') {
                    $newdep['exclude'] = $dep['version'];
                }
            break;
            case 'ne' :
            case '!=' :
                $newdep['min'] = '0';
                $newdep['max'] = '100000';
                $newdep['exclude'] = $dep['version'];
            break;
            case '==' :
                $newdep['min'] = $dep['version'];
                $newdep['max'] = $dep['version'];
            break;
        }
        if ($type == 'Php') {
            if (!isset($newdep['min'])) {
                $newdep['min'] = '4.4.0';
            }

            if (!isset($newdep['max'])) {
                $newdep['max'] = '6.0.0';
            }
        }
        return array($newdep, $type);
    }

    /**
     * Converts text comparing operators to them sign equivalents
     *
     * Example: 'ge' to '>='
     *
     * @access public
     * @param  string Operator
     * @return string Sign equivalent
     */
    static function signOperator($operator)
    {
        switch($operator) {
            case 'lt': return '<';
            case 'le': return '<=';
            case 'gt': return '>';
            case 'ge': return '>=';
            case 'eq': return '==';
            case 'ne': return '!=';
            default:
                return $operator;
        }
    }

    function raiseError($msg)
    {
        if (isset($this->_options['ignore-errors'])) {
            return $this->warning($msg);
        }

        return PEAR::raiseError(sprintf($msg, $this->_registry->parsedPackageNameToString(
            $this->_currentPackage, true)));
    }

    function warning($msg)
    {
        return array(sprintf($msg, $this->_registry->parsedPackageNameToString(
            $this->_currentPackage, true)));
    }
}