From 6bec82a13eefa5bde341e66f2bfc86948002ecb7 Mon Sep 17 00:00:00 2001
From: Daniel <dl3g19@soton.ac.uk>
Date: Sun, 25 Apr 2021 22:38:45 +0100
Subject: [PATCH] Fixing issues with >r dstores, timeouts with DstoreConnection
 receive method - needs testing

---
 ClientMain.class                      | Bin 3428 -> 3428 bytes
 ClientMain.java                       |   2 -
 Controller$1AcksReceived.class        | Bin 562 -> 562 bytes
 Controller$IndexEntry$Status.class    | Bin 0 -> 1162 bytes
 Controller$IndexEntry.class           | Bin 2220 -> 2250 bytes
 Controller$RebalanceMessages.class    | Bin 513 -> 513 bytes
 Controller$RebalanceThread.class      | Bin 890 -> 890 bytes
 Controller$Reloader.class             | Bin 436 -> 436 bytes
 Controller.class                      | Bin 16309 -> 16856 bytes
 Controller.java                       | 103 ++++++++++++++++----------
 Dstore.class                          | Bin 10483 -> 10646 bytes
 Dstore.java                           |   8 +-
 DstoreConnection$ReceiveContext.class | Bin 0 -> 3277 bytes
 DstoreConnection.class                | Bin 3365 -> 3634 bytes
 DstoreConnection.java                 |  97 ++++++++++++++++++++++--
 DstoreDisconnectException.class       | Bin 0 -> 291 bytes
 DstoreDisconnectException.java        |   7 ++
 downloads/AllStar.txt                 |  68 -----------------
 downloads/Grandad.txt                 |  14 ----
 downloads/PumpkinHill.txt             |  68 -----------------
 downloads/SnowHalation.txt            |  36 ---------
 downloads/Unknown.txt                 |  74 ------------------
 22 files changed, 164 insertions(+), 313 deletions(-)
 create mode 100644 Controller$IndexEntry$Status.class
 create mode 100644 DstoreConnection$ReceiveContext.class
 create mode 100644 DstoreDisconnectException.class
 create mode 100644 DstoreDisconnectException.java
 delete mode 100644 downloads/AllStar.txt
 delete mode 100644 downloads/Grandad.txt
 delete mode 100644 downloads/PumpkinHill.txt
 delete mode 100644 downloads/SnowHalation.txt
 delete mode 100644 downloads/Unknown.txt

diff --git a/ClientMain.class b/ClientMain.class
index 250637acb0fc3986e4b8af3524b3940bd8e03e7f..0718a90f548d9eaebf0d35de7656a22ea70bea63 100644
GIT binary patch
delta 140
zcmaDN^+ale7<a4&13!ZngDitDgCc_;gFb^6g8_pMgFk~FLnebhLk)u=Lp_55LmPu3
z!vqFBhG`7;3^N%V7*;YkF|1>7W;ns%!f=zpnc+TzFT-O7KZY+1z6`$@{1`bH{293!
t0yY<OXE4eJGjK43Fz_;jF-S3lGsrMRFc>jJGB`6tFnBUVPyWG^0|0#38^-_u

delta 140
zcmaDN^+ale7<a5D13!Z{gDitTgCau!gFb^cg8_psgFk~lLnea(Lk)uwLp_5bLmPt;
z!vqF>hG`5A3^N%V8CEhlGpu89VK~9y%5amxh2cJfKf_~&0ERCN{tUku0vI_M0vWj(
tf;Ja(XE4f!GH@`2G4L`(Fi0^(GRQDQF&HsKGdMFuF?ce>PX57@0|1CP8}|SJ

diff --git a/ClientMain.java b/ClientMain.java
index ec60cc5..8645bd6 100644
--- a/ClientMain.java
+++ b/ClientMain.java
@@ -37,7 +37,6 @@ public class ClientMain {
 		Client client = null;
 		
 		try {
-			
 			client = new Client(cport, timeout, Logger.LoggingType.ON_FILE_AND_TERMINAL);
 		
 			try { client.connect(); } catch(IOException e) { e.printStackTrace(); return; }
@@ -74,7 +73,6 @@ public class ClientMain {
 			
 			try { list(client); } catch(IOException e) { e.printStackTrace(); }
 			*/
-			
 		} finally {
 			if (client != null)
 				try { client.disconnect(); } catch(Exception e) { e.printStackTrace(); }
diff --git a/Controller$1AcksReceived.class b/Controller$1AcksReceived.class
index 006d665a491cd54080fef1132fe21d339e435a9f..de2954fe46168c4914df9082fb7b12d7647ea5ed 100644
GIT binary patch
delta 37
tcmdnQvWaEGTt-ey22Lg`20kY1$;%iGSZx`&nCvFsX4GPIn9Rnc0|2J~2qXXi

delta 37
tcmdnQvWaEGTt-e+22Lh520kYB$;%iGSTz~An6xI}X4GQTnaswd0|1`42dn@9

diff --git a/Controller$IndexEntry$Status.class b/Controller$IndexEntry$Status.class
new file mode 100644
index 0000000000000000000000000000000000000000..538373f672d4086f88c7da4147a9b795369b667b
GIT binary patch
literal 1162
zcmX^0Z`VEs1_mnzYfc6x24;2!79Ivx1~x_p8Rz`GlA`>aoYW!}&%Bh>3fH`nqDqzE
zlEjkIVnzmbl`u!2P}g8a2Ki_od`hjk7&sU>*%{b)7`Pa?85vlUbMo_285u-0G<~uX
z%M$f-67$ma{gbj%lS{0*7<d`@*cteF7z7vu85#Hx3S9F_a~T=f%Mx=+Q~lEz8B8^h
zbUWuH78hG12?UoEW#*+@BijHn0BpW64}%DUC?f-#O=ezZi5(+@7_w1Not~Ou91P-&
z41&QS{z0zso__HGLH_PRuED`v3``8dps<qSVGw7KW@M1V?|lviSw;pvh%wIoz5zb2
zA+8|p@;nT(4ALA7ii`|GL9V|3VJNnMR4DT>D1ua|GBWT(RUjLn&cmPzvY!ncCdG^l
ziW-^(qJoiu#W_DEm63tpCo?bAuQWF)wJ0PpDJPYY!3awrXyW%7BLin}W_n&?Noi3k
zBLlOBW*8#_hfQ)0G*}Ig;sX@;Huz1mvu0%A3eGPrN=|jl1i6SGk*f4S>41@e!!NbC
z#3R4Bgq^{Zk%0>#&&a^znU|MZ1WpI3#q10gj0~a(X{7Ya$iRh2%!~|dkmT%O$iT$F
z%fP_E>L3Y<R0akINl@&7X+;KUFs%xr1*AZ^gMop8g@KbngF%ylkwJ@rfkBCZkpTp_
zHZd@6V_-kPz_EdWfq{`hn}LCW4J;?Zz{w!MpaWOW1Qz8IV$#~dz;l3s2~#~2D48-a
zfz6j^U}j)uU|?X^(w5oIAhZ#~a9sul1||kQ1`Y;&20f@HH4H2uH!+0lW?+gG5@X)Z
zAhDT263mfd0dwTQ90gV|M+wYPVFPp2*!MCpMKW(<kPMDw*~B0h9Lc(gK`A(rZ4-l9
z@MZ=^gbTzNSQ!`?L>YJ)#2BO)#2M5XBp6H>L>O2YAZ{{XFa*2Jh`|_4n=qI$Ffa%)
SFfo`jm@rr}@PJuX4w3){R{Z?{

literal 0
HcmV?d00001

diff --git a/Controller$IndexEntry.class b/Controller$IndexEntry.class
index 64003c3c96a02e9e921e9d6eb5a319357ddc74dc..dff648ecf50c78eda664bec5691882c2ca402a68 100644
GIT binary patch
literal 2250
zcmX^0Z`VEs1_mpJd@cqi24;2!79Ivx1~x_pfvm)`ME#t^ymWp4q^#8B5=I6#o6Nk-
z5<5l)W)00S*8fnz$-u?H&CbBX!@$eH$H*Y+oS#=xl%JE6TBPEcmy%lHnpaX($;iNw
zmYI`UoLQC1$iV2u&LF_ZAPlylv?Mb}-?6ADvC=2AxP*&=pMjZ+L6|{=ok5g`L5xA1
zkwFxp&KYEGa!F=>UNIwsKyhVWaz;^pUS?Hl3P>{}gOY|1LNQ3lS`%FW<XlM}1}O$<
zMh1@JlKi676sJl?1_5m9WO*3m7~~llc=JkglTwR9@`FL@85tNoIT;igl-L=Rc^Fg}
zR2dm$uzFf0xFoTpw3v}WFgV0N$Ti;6FFqj1-#y4RIGB+^&Ig|!YmhV5c^EW6rn41;
z&EaC;V$kAY&}PtKWZ+IrNdY?s?08lU&nV3>E(SdYeRc)|9tJ}OBSr>6a7ch7&@-<j
zH9fV6k%7G|F{d=uKaG(=Ov4izG{`Efxfx6tOxYRCco@tXEEpO1z-EA>2o#!(49tls
zDU1xF&|n5@g`^H^%_xvwD;@@G1{+2O7D!ApYiN3c(v=+#gFPrwapvWhWTsU*=H!4B
zJMu6%F*q|auqCFXIOgOqGDt$r1zYG0k87yet~?BGAVXM_b5awFKn8g5FnEHT$ySt_
zn_rd+67uF@@L}*}WMI!McFip)sRSohu+#i`7y>}HaY7V>E#wT&OwUU!DJ@E6WKcy*
z0X7gm*pJWvw6?QmWMFa5Pf2BD;P=VQOZ9`Ki^QayR7M8w;?xp1cp_)f@X`!pWZ+Im
z7G&1Y^kQUS(eMOG@dlS9CTII57KA|b3nTj;6x`MzRT}7`*xdzE%A1#3?wFI4pPUHF
zA&d-s5T7E_3CJ-Bo{$DK1%QJaY#}3qI))&2`#{+*wFK&aSiayaPA!3@c|{HU2^{2L
z&UA!&1r1I78W<V4g7Zs@l2bup%*eox$Ub_YRLaP};g?!m;*nom!p@M*$iRh=XJp{<
z%*#tHa?VLCE>10GWZ*(BnAjjLW>91RrBnt676ukjNyY$TNij$>Ffs%(FfcGN1TnCH
zN&~RC27@XC0|PGuBdDxoU}OkpU|<MhU}j)sU|>+w+RnhJCBneIm4Q=hHv@m<b_T&6
z3_@EOB(#{fGRSCcVo=!1ptg~Lfq{`Bgn@xUih+%RfkA<Rg+Y;ln?Z>|l0lh44pgi#
zs4^%rgffId%~xVzW?*JuU|`dd-^##=&<}C71_LXDCW9hFI70+fy(|M0*gdRTTNpUk
z!mVQi3+gZ^GH5eILX|2rFf%YQFfg!dNwaKY&_p-efPsy{5UfE5sv!VWS1>RzsB3Lu
zkdWTNpu3a7n28}A#M{YW$;hC!g+XQ^1Gmgf26nA&47MNxnZTaq1AD=QfsetIL5;zT
zA&P+k6l`i>)1w)fz#-|$zyx-V0?0h=oeU0`Mq@SBl7XASib0;i8fL6KH0oj)6d7U}
zV8)w5jTZ$OzmvfQ>|6<`Js_t-;sxSVI|fb$dj=5(2PC87-~s0WHA)_26eJwn;g0oU
zWWeEnX9hk77X~>7SC~WP7!(=e;0|<!nkoY_ReL9c9}z}+FmN+?GDtIc!HkrKJD8Cn
zo*@Amw6YA0;P?k63W*J9iNY7EC6PgqAqnnBC8%rIw4}E($RNT8lI{W-SQ&yC6d95k
zQlM!Ap<Wv$okP@zGO#j)F(@*mGNeJ(BRfeA-AR!Q%na$^?3cli38u3cau^sGgcz6@
RxEQh+av6BQ88^>C5&%05$^HNU

literal 2220
zcmX^0Z`VEs1_mpJ0!{`d24;2!79Ivx1~x_pQRn=;lA`>aoYW!}&%Bh>3fH`nqDn>v
zwvvp@Vif~M1|A=T3TrL~4hBwk1}+{3ZU!Dk27#=^vPAuy#JqHU|D>$c<Pt^(Hk-`6
z%o00B24)S-FxLN20J2nohe41*h>?LKEi)&zII}91k%7^Rok4_=K^SaIX-Q^|zGG2Q
zVx>=JaS0cLFaswSgE)f(JA)(-gA{`_BZDYHoioVA$t9WjdBuzj0>zbi$r(lYd6`wI
zDIm>^3`!b42*n^FYfW?kkeg(A7~~k_85uZ=OY)0SQ=BRp83eGYQ{-V#Vo+ve;LR(|
zO-d~a$qxppXJlaX<X})`WDo>vSIEp$C@9KLFG?*g1{to-!=S;S$;iM~T#{H)TFl5G
z1Th*MUcn_rnR)5fTntPM+B^(847!XA+=(eEU~|FlVAb%9(hTEb&}T4UXE5YpFk&!f
zWDo><3T%L9UP)?tY7rv?ds$*mX{vu3BZHWRC)Ah7Dy+E~Oc~7B8O(VYEEp^q8Ti0v
zfI}M;FpLb$i76?J45H8w18arErnP1iNUt>ygAIc%BLfR0(wH?gJwfTfo`=B!ln6NU
z@=G$)DjjojK#HAs7@Qeg7#Y|SQ&Jprau^vTq2_`uL_{0ZY&RYTcaR~h$vLTsMIZw_
zc^JGv&SWb}&CM@M1qu1^F!(a~F*2}c7Q5yalvIKf7uab5JPd&#+c+VL!4`4`XQt;R
zmXsEyGBT(_LL6*2$g?&OKG=`Y0JOHVW@O;kKu+bFVT=qc&iN^+j12rfnR%&xkVsEV
z%1LEp;4V%raf7E|77Z_uYVLGoL1qn2FGdCy4Ns61Z*WOsa<*?`K?p>@FmiZ++++<>
zrGYMr-K8L<ym_hRjyXB`$%&xk&&a?B@jD{rfE<J1328vn1UwL|85z_u1hLx(%3G-=
zQ2)acJ!f%hNiZ}?qof*Wng%(NGaaEu1ZEjH*rAFT8MuP;ON)|IL1D?rz>g?o^g!v8
zk%7Z6wYbD1zqo{*A(xSX3n9<Qz~h;hms;eUlUQ7wTFl76g($Ze6d9NpI2afhSQ%JA
zr40iE0}CjJGcYm)F)%PNF$6QPfO0ZeT!TTAfk8k3R1PvQFz_-kGH^45FfcNNGB7ZN
zF)%YQF)%P_X=!g|VAR^qz^*02z`K=!Uu!pmaO8Fd(H#t8TNz}un71-0XbGuoWl-D5
zz`(%B5XQj3AjQDOz`!8Mz{w!RAiyBaAjcrXpv)l4pvfS|pvVx;5COGAiGi7cnSp_U
zO-p_&13yAPs7zpBP-I|bP-0MIh-8R@s+VP8VqgUMO=}AS|5~_pY+ylE21N!PhG?i#
zWvKJnwWL|LF=(Nit;xW~pas^T3)K(+sudU*7}T}4Fvv*nV9?viV8X-@4&v=(uwrD;
z+QOi)kbzrfCIh?HHU>M8flOe}@`1ge%fQE=$Dqcb&k)1Fz`)GFs0KDYmVpTznw|_y
z;Lub6nWw#z!4cDFti~EKa5ES)$TOJ0jFpE*V;qAbLp%e_cvGnHq9EgUGPr`BD+9F$
z<Wxw!K%8pMz{z02Ai`jYWK;q?;5?v4$%Bl7go6j%vEGafIQ(zJz{g<AAje<_b0{dL
z6W|VXg_<e@GF5vggFg{QIx=uGI59{wIKzyThC7&%A(0^o8nm(ujNtfZ1sS~oEm62Z
zwInkrGNi!$s04Klo0jxe1_ea;K+>HT11p0!gCavJLmD(~Ak=H4q;rURKL%C?e+ET{
sbcPJ5dSoZ5p*tyvfteu_oE5VevcYr?LmmSI0~Z4$0~13ILp}ow09&HFT>t<8

diff --git a/Controller$RebalanceMessages.class b/Controller$RebalanceMessages.class
index 80d167489f739ee9eba94387b9449faf8167dd0c..8f171388f336657f23cacef98aa5d8958240084c 100644
GIT binary patch
delta 13
UcmZo<X=K@OkC8Ec@_j}n03ebCj{pDw

delta 13
UcmZo<X=K@OkC8EA@_j}n03dG!hyVZp

diff --git a/Controller$RebalanceThread.class b/Controller$RebalanceThread.class
index 33a49d5601312bef9a9513a5464c7a61da1c5024..25e1c787e72efd4e87508bd8fff5ab539839fb1a 100644
GIT binary patch
delta 43
zcmeyx_KR)9G$zJVlczH^OP*!mW;oBl$8eT`pWz&X9K%Hh6NXC+)(lrC8#B8D07t?N
APyhe`

delta 43
zcmeyx_KR)9G$zKwlczH^OCDq3W;nsX$8d~+pW!%z9K$IF6Nb|a)(qz+8#B8D07Hxo
A7ytkO

diff --git a/Controller$Reloader.class b/Controller$Reloader.class
index 506b3988a3dbd4a35223a628cb012c5b5a9b92c7..fe4456dcdad54991ba96e5ef3e7972b65c43e9ab 100644
GIT binary patch
delta 13
UcmdnOyoGr~CnICh<Ss@n03oylQ~&?~

delta 13
UcmdnOyoGr~CnIC@<Ss@n03neCO#lD@

diff --git a/Controller.class b/Controller.class
index 514327fe08525b5aa27de405c9c8ade4f55b05cd..f8f4f7fba84db7c0c456b8882bec45b194ed4beb 100644
GIT binary patch
delta 9956
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

delta 9428
zcmcc7%(%6l>(swp`xqD)teDa_auu)%i)i>{C6*=X=cShD2j?eer<Pc6?qh3U=AO>T
zz><?$T*ATdWU>L58TSi@m+TC$co<$YyqR3cWzP6+@=7jK#t)P4bD7J3;$isA(8tKY
zot&Rnl9-uS?44RE#K6R`h@IgZBZKH<Mjp|0E{3lRY9Qh#55q5p-;500#i=E3nK`M&
znN_Kb3@jR6nqk}wGa3H!F#Kcq&&a@*omv^3TEfU6sG$jQVrfZcj(%`zi8VJPBO?<#
zBQp;p3nMEd125PEP}#|EdDOYt89CS)Ie8el7`Z3Q^O}3|@-Xr-WH2%a6sMN>mF6a;
z7KP*om*f|vaxe-oGH?Wk_y@Vhhxl_b7&8j-FbXs5U}WIP%qs~?%qdM3Vqj(z<zZON
zD8|U3K6xUS@Z?Rr5^NGY4C@&sCtu*T5s>C#lmYpNr93gSgq=}tvJ9UxuPj3(7sFRZ
zMIJ^aM&-#qe5z8a4BOZl)fgH05U%wB1uvt<<Z?cZdJaY{Mh3oOkfRim^K%PwQcF@f
z8NM>=@G$B!>M=5~6_+HIlom5G2tfiPCowNwKe(hQGcVnmgVBJIfe+#fXMf)SAJ-69
zc19yc24S#Wnfdyj{;n0tsRbpO`FUK7h76HH46F=`xEW?Ln(;82Gg>e*Ob+8VkYKdp
zVYCK?6L(@t3OIaHoGLjOZ71{bOV-;nG6*~8=am%Y=j5aosRX6w<R_-27I87!fuoht
ziHFgd(S?zLI~_S%nKd-MI2r92-FO(?89f*oIMU!T&gjL>sLII1&B)H^&BN%!=*!5!
zo{?DWms(N6$iS?j8O6nD$LP<)7ywFH%)E&yDMAcvj6tBN2%fx-U&qXjVVe*GJEJH_
zT{sV81lWYkV%OY)l1dK7C`JY@*PtN(pm-mDM;DNq7?59MCkqHjiP|y7^Dx|H=o4b#
zU`zy=n8e7SF?l1u$mC!F5hV`B6h;Q2qSV~{vQ&l4JcWXy{Pd#K;$k5NPR2A)#HUX#
z6i8;woP1S4J0Y8qfgh?A7H^<{&E;XZ%V@#Dn9s<-ALQ!mALbeliy98bLPiDwx73p4
zjLf`r1yCl_)6?T%EM{b2_3;c2Q4nI_Vk`x@s*I7r0-WUHIfW<Z3X0fQFfwojr{<+(
z=B4ZD>2Wc%Fjny}Rx>m(GO&~sW#)1+C^OdbFxD|BF*0zcfD;oqhY2xoGfHqUHcmbu
zsKLd>z`@we!`Q;uI(a6Kxhp$kJ1n7qvyfv^QDP-1WpXjLF))LosEdcO8x#i|u-pw2
z^ygyiW9(;VoWR34k#W*wT_HurDU<z$WO*lpk^=|hbRNbTj58-!3Tc?mW@KRCVlZat
z0qKheWwQA^j0-@H<|xUBBw<h{D-~kkVO$LI_7X-0OR%?J3Td$|1Boo3EGaC*wh|Qf
zt0r3umocuHyh&J1Y%=3I9>(?H?3$hm$*vrX8z;XL_F>#S*;+(LY%33=HRCo$238Hv
zD9tcXj@-e+xN~x?h<MyGE`|WcJv@wi8SEGtSPP0W^GY}v_cJmuf&=Iv591*QHbw@{
zqSU0soW#83R1U@?j11h66y@q05E9A7z{Gfrhw(T_8Cza{NoHClDB@4@FrH#OJ^7P}
z8s}M1DRqvKL1Z$cs7NZv_ZN5=0~jwdGKgt-B4uO$q^#8B5^K#ckdkl?#w&~rLP4%h
zjy{fl&WL2g#W0!i8V}=j#xhVrk(!s{n3ocinw*+hmMX*`z<3iBPPZm66tzp5%y@@~
z@h-?+ESY)9MIeXX=V5#R65xb5)G;TAo$(PPgB-Yk0GB0xr8zkP`I&hosYOU-#Y0dz
zHkt7$594))C7_h^oQLrR<IBl;Vx|sn7#X;rN!!ucTZlo3@g@i3dqxIMNJ-@A><x1A
zM;^vc3`-ap*oz=;1sU>%hw&@px5<yitOSCD7(^Ivf&_o@F#cxzGg(*Mnu+n><}7h>
zMix#+2I0w$;=+?>NbocAOg<<fF3HZs2TQJCXNP1I<(DTW<)ltF64PL2WC)u4Q9^uj
zqkyomoi%d30ZP#}Ao0zLl2;k|6u6ianUvU>lzA8yGpS5wkv^iX#>gP#0?soEi6sh*
z3R(G?d8sM<Y)l$lOqxtu>`dA`Ogc=uo8L=wF!C92F>o*$@-Rs<NpUb4PiB=>kT7Lr
zU}jWc<Y#9x2T5A+Fi9{8a4=a-ww0A-w3!?&tH5YCxklD0$$^o97gQ$2y9N3CDnPV2
zfwVaDFo`jVb1=DrOkz~vXJ>K;348D`iGob>Vq{=pRA6M}VDe#P;D#p<u$6uwh5kHD
z!b~C@Oo5XX<dj%~85!IrFOZX&oFu2iAIiwU0f{RGMh>R%$#dnL86zh@l+$I5p3E=b
zGI@@?6iYHAgX&}hX;n6Mrc_1-xyc67a+8@AtZf+oGcYhPF)=W(FlaGoGk|D41|<eY
zs5m173xgpNpNT<)fsuig!I6QHiFtCBLZT%L0|SE=0~Z4WLka^6Ln;F&LmC4gLpp;n
zLk5E+LnebdLl%QELpFmWLk@#KLoNd+6Dt!NShtAc<a&^9KL%k228Kcgc7`GbK89ij
zQHBx*S%xwOeTH%dONJ^2cZO;PABGMFe}-Cy0ERk-2!?uwNQOp+D2676B!*^&WQJCT
z6oxj242E`wOomP-b_NCpbq2Qo4EhYL>`WYtjEsy744nTNL>U;_nK&32*%@3t*%?AS
z*%>UvSs54^To}OaVPIhFWME?e={`Q$Rw+QlUTX`3yd*1&(GCWq9Sr@u874>SPF||y
zQD5e_iD915#%&D#AbRsQ2LI*%lYF$dF+^-+U}mUcXkch&Sizvcu!><Vg9QTv!$F3F
z3>FMbOd!vOF^DoSF!VAAF!V8qFic=jV3^FH$}ok&l3^-?E5kH~K!)iIxePNHY8YlR
z^fJt0n94AhVL8JVhE)u^8P+mvXIRIu(}rOi!!Cw>47(W)GVEhG#IT>?7{fuZuWcCE
z{xT@AGeom9r2J<{Vqjxu;DGSh8H(5$a@m<UCa+MI;Q-}D1|}xv$!C<8*FWCI;J*=^
z2te+0V-RFuV7S5{z;Km8hT$5662o-{HHI4unhZA?Oc-u4I5FH|@MXBm5W#StA(`O;
zLmtB;hDwIV3@r>#8TuKXF-&K8#W0`Y4cIxH4D6Z`qN1Wg>`b8a!NR}@4vsSnXF--T
zFfh9^urSo~g92WJ;i)-`?hc0M<}6|?TvO&SaD#&OEhuOic&*q#ocG%p{I#|)=;-WZ
z_{hXClR<Ge!_G+UZ4A4&GwiowlVsD`#qfoJVH?8{Nw#eaM>p<f_!_CTo#DF`8(5Ph
z+fIfV%nad@Y+@|i7=CDNVc^}%U~I*%CA@_}KGKTg5Gb;DGW=m=*vZH+`M#<IBirO3
zs!D=9$hL3@GxAT?R#OrZ+{Gxuz+lC>n;|+<OOkgNqxj@_HO+dd<qTX_+>+ee8096|
zwlON~WK>~f09mz&foBuLJYh!lZ4CaBT!)u4a9i<7avhfB+b_u`%&57QQCpHjm{A|(
zc#drhM?uE0flM&o$iTtC${@uc%MilQ$gq`R2Ll7c4u-uTno*b0oY9I=mQj~6jxmve
zfibb3F%86EP-h5aY-BWK2x6=Q(~y+6k3pY-f#E#^E5k<yZiY_`LJVIRq!@lN$TECq
zkZ1VGpw94@!Gz%-gCoO#1|LQShCoI}h9E{(h8RXRhD=6wh5|+|hDt_mhDJsnhKY>4
z409Rz7}hZIGHhZLU^u`i$Z(ReUWDNqqbS2|Mlpu3jN**Uj1r7OjJk}XjAD$^jQWg9
zj0TMAjK++*jHZm{jFya6jOL6sj24WJjMj`njJAx?jP{I~j82S&jINB8jBbo|j9!e5
zj2?{5jGl}gjNafRwTwaV4}%no6FWl)r`CT4M+Po%5-(zBXkllNXklSz_{z@2&CbBY
z&dAQl!0?kn)|H)!ck)6Fsd{d9hMgc~Ox&RI;0J^8e+D@e?Fijqbqq`ljO>iEY?2@o
zelf8BXAoy#MY64h1tf3ChMcxRH6J8xGbA%GGk`Lb5jgqnWT^kh#4w9Na5sZRq|Poz
z69$Iu3^w~Aa*U=-3<ns#`sr$KV-(!RXo<*;VhpSd42*sZyo>=1(u~0jnv5X~hK!-$
zpkQWTlt#9j;S$4Th~12q49wtiY&OJvP=1+J&mfJIl>Kyt8Ev*P9MJ`36^JUBD|R#5
zMQUwlbg*KPWYOKm=(v^9RTrF=JsBCSSS49^GI}vG%w$jpvDg?H4lo#7u}QLkQmbG1
zCWd*EY`Yi(LHW>s`Twh0TNw1UC0RgOZ?c~jf4%WW1||ju1{H>>jD`%V43oe#BzXog
zh%hiPMl$d+Mlnb-Ml&cd#xSTb#xkffCNdZ^CNbDDCNsD(rZ5CDrZPk`rZJ>5rZeO-
zW-!z+W-`<>W-;_I<}yrTEM%C<n9necv4CL~V-Yx*R2W!Q|1oHT5(XoS9XliY<cC_q
zVumazL3e}UGPp|O(w3_ShXbRX70V`uc{-9T+ZaQ3F@}OY1mc9vWZ=~mW{lj%aAY}y
znj{PJHpXaB5U@(JNV0BYj0@M5WR+yu!sxn-F#)6r9Ky>PIQ(?CF&b}VU}RumNM*=i
zG=x?MW(>Rx42)$AJdEWG(u@@hI*j#|3?__K40epQ44#a241tXG42g`545^H*3>l2g
z44I5A47rSLV6Q1Ku>57P10`!lJEi{&Yz)ls<OxoipyYQKo+xfYE4N3G=msYWENP-1
zYogE<W=!77sEtSnERrnHgrEjuK@$Qiq(EfV(cQ(E3QFP$+Zd9U|G%aiX~l9#S8EG{
zK<hR}a4E?O3N3j_7I0a}CdqPGl5IcO^m<U4IS*Q1W^7~d*A-^W+RCU6aW!KO6GJ#s
zItC?DVa7aA!N~$HIAH<J%1{ofhZ$uV${BhYCNMBCOkkJ_ra{T?4mkPUWB}2S<X6NX
z!@$7U#lTz7*v%lx*u$W}*vp{8*vFvCIElfSaWaDy<1~h7#_0?>jLR7E8J9B@F|J}L
zXI#V3z_@{-nQ<LME8}{GF2;=vGZ;5BEMeTru$FNr!xqL}4Eq`PGMr)D$8d#lKf_JN
z!wh#A4>H_kJjC#j@d!8)T^YDk|1!vf(<l2c2A%r<3<4<S%vW|;Ndzs3ME*1AVMH}b
za(=`x9a0i7+-6_~6(J01;OeJf8-u?vW05Z?EMavWBZHqVG$y5VcQUfogR*ps6^o7}
z%Pz(e1_s~d{~sd-IH>6(%vcVJ7oBa4mCzz&IRl5U4m^R!G9;iS@DmK2jHeiQ8Ba49
zFrHzsWIW4Y!+4ItgYi5=AmaswNXCl{v5Z$45*RNtB-S%tVMt}X1`Zo}Py&|$721sK
zzZm5IGbl4KL6SHmeIt7s)TM)XnrjsUJ192U=CRo9W)O?q&L9Euu|}jHsFK&%!dP>R
zflc@DMy)Lj8ai7UYmjSxMg~hzl7a?^3YMh3i?JS&uy26OfF<k67xl&K8$hiT9dO`o
zV{Ecw+0ED%xt+1Yid73PxRVi7lCnv%L2U^Jv7i}<T}P6AC!_>Yg{b3@<bbNv0I|U8
zTC6xFStU7lGIoOM6kZ6shlwG4`Q&&5xq4`$BLm{Gt&9vg?K>EI`^-2YPT0xFz{p_5
zCCLRf*961@n`>;vEy*Uy4Rtf9)Mf~mWJeQN{{IA{6&I-V2YG{Ak{fEw0}u;jOg%%3
z6%Vr+uP861=@TW%b&P=*WQi9e!z=~?3|D|OF&JC%=}7Xy{4U7@^_;jQ8>%SCn=QPI
z%l|J1TLEg<ZG|+lQWi0Qt*R%_u9*ztlI%F_n!WtL%x=cXpn7qt6*nkVfc(w_awVuT
zWLyVgLA}9S4-G$%hj?Kgf<z|2BtJB?E`eBJ9W7P@TA<o<+Drzv<qW%o8E07uf_w#O
ziZU`-2}ue;HC2IFU`@tW!jim_!rK_<fOP$TAju{v46~{pVwZ@d2vnORhy~WxVkIgm
zASt?yp?fBS2C^PW(VdKQnHa()1wn?++r_w$fx${}IRo4B|GSs}Z;}*{6x_yGDb%=)
zp?ROA;4a2RAZbZHNx_|rpa@z1Ukem+DvS)f7?;*FFj(<}xS%i+kQ9KrLKeh=x<XKr
zA7l#168`1??@RJavP&Wb71$h50~<}8I0Ng!CRzzV>LOlA0ZDF9S+)Y6ZU6a6az|S6
z9NGkGlCK6e$+=;97}R!O3yNPAMutTUf?yRJwlVlK+bn00MwVOxt)Vu7yC_^%ypp`2
zRzJ_-<qVVm7)#VcdlHNcAQ@-~EC%@z90JBxe8}k<5@CqMp^uU{wlL^`f)3J1l;qpS
zD7b^6e;cD9^ESpU%m1H6PPA}?>Y-NZ5oOXg#_h}hpIiPvQWE5TZYyy~p2L#jpw_7d
z<5tF+O$_tkMaeG4U7%(SxF-fK<shXAqB$T13O!gY!U}2-vTkGCz5M?pa9HjGu^IM(
z%GhlT5unnOObZ~j6b|#_tm-95Fk4bm5*l1mAQm`=TCAi%ZkGbN7s>6C68m)zgSuzZ
zx`!pD_e;-WVAtBlcwi#~4~sKPH%lL*EQ>SC43^pT3=Ax@Sr)L&W?*1h&zi-W%fP^z
z%UT4Y8Pr%yS<f+8fM_;71_su1tXDxan;x41h-MIEkY(#*U|^7A>ju$meQc9JG^EAI
z_=};Afr0TR0~6yd1}?@s41$bz8RQu6F{m*<Wbk2p#1PH+njwy{{tZJS<2#02#`g^M
zj2{^~7=JKKVf@K3m+=?F5ysyPZy5hD{9ydc$i(=ck(G&ok%NheQILt5QHqI$QI?67
z(Ta(UF_wv)F^`FZv7U*Ov5AR`v6YFNaS0O-;|3;P#{EoujAxhx8E-HNF}`IIW@2RG
zVPa<zXOd=;VA5ieWHPU3l3{XYl4Xiul4HtY5@#x6Qe-M+(r2n?GGLm=WXQCf$%yGZ
zlQGk6CR3&dOlHh1Oy<mjOcu;mOqR?pOjgVhOxDb4Og7A!Om@sUO!mzAOb*PgOpeU`
zOis*`m|U0_Fu5}CXL4gc#pKR>mdS(pIg=-g0FxJsG?O=r9FreQy%Li@i#bygixpEc
zi!D<ci!)OOiw{#KOBhoYODa<iOCD1$OEFVEOA}K8OE*&~OCM7)%LJwpmZ?l-EQ^^c
zSe7$YvaDySV%f`7&2pTnhUGF-Ez2LKI#x-hdR7^x23A+5M%F~8Ce{?DX4Z737S>Xx
zZq{0+9@dFWy{y}r`s!KtGxf6`Vw%8unrR~IIi_~j3rroXSDCt5?=tnUeq`!p6KCpU
zlV|E@Q(~IHrp+{wO^>OY&4Q_i&4;O%t%#|Qt%|9it(Iv5TN~3vwoax=Y*U%0u+3$f
z3ThWI&SG%*#~{bZ&M=dmf$0x}I6J6$q^0(cL6w~mg6i4-GN`jN7_&37YyV_m`o+NX
zpTUlSo1K9Jstc+RWWr2FMs`Ma28Le@R(~0|*%{f{8QK3bNU$@sFpBe-{9<7J!@$HS
z&tvkFf%O*y(_aQ5cE-u<jO_my48RtsvNN*(VNhgeXaPwvw1BzwO6&~Ae?Usve>1p1
zT=0WI=`VvAtTm_nhd~GIZe>tEoClA~*cm4?F#KUKWoKX#cLMduq3z(m43dzJ{$B<S
zuuIr~F_=Q^{At2q@{559r0_ojI|B>CbdX8fV0#t3*%>VUFc`r&OuUm1S*o(|g1U&W
zEhX!De=)G33|xW6#zDPA1_nlF24)6M1_p)&(5l`~huKJ&@$fc=?pX|$I-t^RpBXE&
z8Jj4ZDC;5ybx9UcHX|!`P_tW-9XxzBi-B1e)Y1c0o-J&Q%m0I0lAvA^sNCAZSaZCd
zfnAaX(n#IHSR=iIp<fr$AcHE{$pC5g$b%UR7`Q;<+Zc~RyHp&YE)~aq(12tRLp;ND
z1_p)%hACirI>Q_=4e9uRd!S4+7&w?_GKetEV$fxp&0x*6kfGj%X%>SQ(^7^YrezEX
zOe+|Qm{u}$F|A^l$h3xGKGRxILS(Q74U5P#u!F;wi360VKm)FzK$d1_X!*~;2Mv3$
z97tG{oq@>!6feI(BNR;hOahP~WyoV-Vqj)qU@!+&HQGBF>p?v|P>AhhJOLV%JHyD}
zs{<{j#dLNuf=lVIkP(yZ%l|(|8#H0sz`)J4kwJ=S6N56-W(G5+tzZXpg7S+LJ0rU^
z0|RK54ANs@$c1*3459JqtG%<H@eF#`h!H&4!J@+qs^ZQwGc5oASZ4!#<P<zs!?c5e
zgJ~y&GSe;w9j4t3`b>Mk*7AY!4L>M&Ksi+&I=C*#zyO*@gSsJ;0W{doz@V=U_Hq4A
zkOSaemWFznQ5Do(y98=Tvofz){{Ion8Z;LiV321z$e_V=h(U|#2!k%uQLqbm7?}Ss
z@USzo%l=|ug4!=6z{DiXBm#|q`wYws91IK$$&d(ujDs*t))8jByp8cHXygaP0;O<J
zvq)Q#br<6ea8p1x(u(bn?l#8Ty4x6GZKnkc?7G_+?@6+O`}gdUY=<S;_k-$9aKHaC
zC|Q~?_%Z}AFfar#go0@Xh6sje#)pt<j=`v&fro*CDUd;oDTqOlDTG0vDV)KCDT2X*
zDU!jBDT=|1DTX0}DUl(XDUKnQDV`yTDGBURDF(Jb4EpR0Eq@rK*day0PX=};cE*Qn
z0!*N}7N~c#8JNN8O$*{(aG#4|ve3P4j8DML+<IRvP~y_r#`p}{yL}89zENaQfxA+Q
zfsKKI@d<+j<5LDj##am~jL#WV8DB7HGQI{ohMj>ag`M#sivSa7@&{`31_l;zpF9r5
zW}RJ(uNWAF8DDQ>yb5waeKV*S0TnB+!Oe9^Nfs6(9Wawm7vwTfqm4m$6T>`hNfu_K
zU5szRkpT*07SKQy)V0A3VQ|+ff#R2OCW8XwECvh4*$mE%^BIB}mokJgE@FsaT+9&5
zxD4!S0S1;o4E4_JOdP)$_+cR@0ne!y7+Am~o1o^Kyf&oQ!7y2v@!dAY4<MH}`+`fu
zcVM^5X=&@Q7;R(xyqrM^G<Kl9i}5?up+X?H>wuj811bU@M0gAuBUELm*JUsOPZ#(z
z1i^h^1WFW)QVf!e(hRDMvJAS6N(=^!@(hNIiVU`lN(>H+Y7G92It)RKnhe2=S`6Wg
zx?ms4F|ht;Fn|u47(-`)Eckyh@PWJsiXKTODQNT@V_*iwswji6mbT6|#-FedWrz@F
zoHg0hL0%jp21>~c5t1y&|6c_+ZU0Wrc8~;5XxTCFGcYjBXJBJk%)rU8kb#?F5rY83
zQU+0m6%5i0D;bm-RxxNWtY$D_*uY@Uu#Ul!VLgK#!zKo2hRqB<3|qi17G_`rO;EA@
z0TrMva!%|F7HkYGOw!=YF2f|tz`(%6z{(KIXvd(;@Re~glN<vB!xV;kQ6_l?MkZAz
zbp~c8Jtlo7Juu%0OqxJN&7h)|U{Px@X$vOpp(-4qDqNs^Hz?l|tjZfI>I)SO0E-5J
zNFSyU5XBS*CL_RP6jKZX1A`F*8-p?f2U9Eq3qvde2U8pa3&U3i4yJep7DhV;4yFVK
U7EnFUl*quql*E+6l*S+l0O%46*#H0l

diff --git a/Controller.java b/Controller.java
index edcfa38..de3651a 100644
--- a/Controller.java
+++ b/Controller.java
@@ -16,17 +16,24 @@ public class Controller {
 	protected int timeout; //in milliseconds
 	protected int rebalancePeriod; //How long to wait to start the next rebalance operation, in milliseconds
 	
-	protected class IndexEntry {
+	protected static class IndexEntry {
+		public static enum Status {
+			STORE_IN_PROGRESS,
+			STORE_COMPLETE,
+			REMOVE_IN_PROGRESS,
+			REMOVE_COMPLETE
+		}
+		
 		protected long filesize;
 		protected List<Integer> storedBy;
 		protected int numberToStore;
-		protected String status;
+		protected Status status;
 		
 		public IndexEntry() {
 			filesize = -1;
 			storedBy = Collections.synchronizedList(new ArrayList<Integer>());
 			numberToStore = 0;
-			status = "store in progress";
+			status = Status.STORE_IN_PROGRESS;
 		}
 		
 		public synchronized void setFilesize(long filesize) {
@@ -74,11 +81,11 @@ public class Controller {
 			numberToStore = i;
 		}
 		
-		public synchronized void setStatus(String status) {
+		public synchronized void setStatus(Status status) {
 			this.status = status;
 		}
 		
-		public synchronized String getStatus() {
+		public synchronized Status getStatus() {
 			return status;
 		}
 	}
@@ -148,7 +155,7 @@ public class Controller {
 					BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
 					String[] message = in.readLine().split(" ");
 					if(message[0].equals("JOIN")) {
-						dstores.put(Integer.parseInt(message[1]), new DstoreConnection(client));
+						dstores.put(Integer.parseInt(message[1]), new DstoreConnection(client, timeout));
 						System.out.println("Dstore at " + message[1] + " joined");
 						try {rebalanceThread.interrupt();} catch(SecurityException e) {e.printStackTrace();}
 					}
@@ -250,22 +257,33 @@ public class Controller {
 		}
 		
 		try {
-			if(index.containsKey(filename)) {
-				PrintWriter out = new PrintWriter(client.getOutputStream());
-				out.println("ERROR_FILE_ALREADY_EXISTS " + filename);
-				out.flush();
-				return;
+			//Create a new entry in the index
+			IndexEntry entry;
+			synchronized(index) {
+				if(!index.containsKey(filename)) {
+					entry = new IndexEntry();
+				}
+				else {
+					entry = index.get(filename);
+					if(entry.getStatus() == IndexEntry.Status.REMOVE_IN_PROGRESS || entry.getStatus() == IndexEntry.Status.REMOVE_COMPLETE) {
+						index.remove(filename);
+						entry = new IndexEntry();
+					}
+					else {
+						PrintWriter out = new PrintWriter(client.getOutputStream());
+						out.println("ERROR_FILE_ALREADY_EXISTS " + filename);
+						out.flush();
+						return;
+					}
+				}
+				index.put(filename, entry);
 			}
-			
-			//Update index to "store in progress"
-			IndexEntry entry = new IndexEntry();
-			index.put(filename, entry);
 			entry.setFilesize(filesize);
 			
 			//Select Dstores
 			Integer[] storesToStore = new Integer[rFactor];
 			synchronized(dstores) {
-				Iterator<Integer> it = dstores.keySet().iterator();
+				Iterator<Integer> it = reshuffle(dstores.keySet()).iterator();
 				for(int i=0; i<rFactor; i++) {
 					storesToStore[i] = it.next();
 				}
@@ -294,9 +312,9 @@ public class Controller {
 							System.out.println("Dstore " + thisStore + " should have sent STORE_ACK but Controller received " + receivedMessage[0]);
 						}
 					}
-					catch(NullPointerException e) {
+					catch(DstoreDisconnectException e) {
 						e.printStackTrace();
-						//removeDstore(thisStore);
+						removeDstore(thisStore);
 					}
 				}).start();
 			}
@@ -319,7 +337,7 @@ public class Controller {
 			}
 			
 			//Update index to "store complete"
-			entry.status = "store complete";
+			entry.status = IndexEntry.Status.STORE_COMPLETE;
 			
 			//Send STORE_COMPLETE message
 			out.println("STORE_COMPLETE");
@@ -342,7 +360,7 @@ public class Controller {
 	
 	void load(Socket client, String filename) throws Exception {
 		try {
-			if(!index.containsKey(filename)) {
+			if(!index.containsKey(filename) || index.get(filename).status != IndexEntry.Status.STORE_COMPLETE) {
 				PrintWriter out = new PrintWriter(client.getOutputStream());
 				out.println("ERROR DOES_NOT_EXIST");
 				out.flush();
@@ -391,7 +409,7 @@ public class Controller {
 	
 	void remove(Socket client, String filename) throws Exception {
 		try {
-			if(!index.containsKey(filename)) {
+			if(!index.containsKey(filename) || index.get(filename).status != IndexEntry.Status.STORE_COMPLETE) {
 				PrintWriter clientOut = new PrintWriter(client.getOutputStream());
 				clientOut.println("ERROR DOES_NOT_EXIST");
 				clientOut.flush();
@@ -400,7 +418,7 @@ public class Controller {
 			
 			//Update index to "remove in progress"
 			IndexEntry entry = index.get(filename);
-			entry.status = "remove in progress";
+			entry.status = IndexEntry.Status.REMOVE_IN_PROGRESS;
 			
 			//Send REMOVE message to all Dstores storing the file
 			for(Integer dstore : entry.getStoredBy()) {
@@ -415,9 +433,9 @@ public class Controller {
 							System.out.println("Dstore " + dstore + " should have sent REMOVE_ACK but Controller received " + message[0]);
 						}
 					}
-					catch(NullPointerException e) {
+					catch(DstoreDisconnectException e) {
 						e.printStackTrace();
-						//removeDstore(dstore);
+						removeDstore(dstore);
 					}
 				}).start();
 			}
@@ -438,8 +456,10 @@ public class Controller {
 			}
 			
 			//Update index to "remove complete"
-			entry.status = "remove complete";
-			index.remove(filename);
+			entry.status = IndexEntry.Status.REMOVE_COMPLETE;
+			synchronized(index) {
+				if(index.get(filename) == entry) index.remove(filename);
+			}
 			
 			//Send REMOVE_COMPLETE to client
 			PrintWriter clientOut = new PrintWriter(client.getOutputStream());
@@ -457,7 +477,7 @@ public class Controller {
 			//Send file list to client
 			String message = "LIST ";
 			for(String name : index.keySet()) {
-				message = message + name + " ";
+				if(index.get(name).status == IndexEntry.Status.STORE_COMPLETE) message = message + name + " ";
 			}
 			PrintWriter out = new PrintWriter(client.getOutputStream());
 			System.out.println("Sending...");
@@ -484,9 +504,9 @@ public class Controller {
 							String[] message = dstores.get(dstore).sendAndReceive("LIST").split(" ");
 							receiveDstoreList(dstore.intValue(), message);
 						}
-						catch(NullPointerException e) {
+						catch(DstoreDisconnectException e) {
 							e.printStackTrace();
-							//removeDstore(dstore);
+							removeDstore(dstore);
 						}
 					}).start();
 				}
@@ -503,7 +523,7 @@ public class Controller {
 				  //Files are evenly distributed (Dstores differ in capacity by at most 1, no 2 datastores have identical file lists)
 				List<Integer> storeOrder = reshuffle(dstoreFiles.keySet());
 				List<String> fileList = new ArrayList<String>();
-				for(Integer i : reshuffle(dstoreFiles.keySet())) {
+				for(Integer i : storeOrder) {
 					for(String s : dstoreFiles.get(i)) {
 						if(!fileList.contains(s)) {
 							fileList.add(s);
@@ -523,7 +543,7 @@ public class Controller {
 				for(String file : fileList) {
 					for(int j=0; j<rFactor; j++) {
 						if(it == null || !it.hasNext()) {
-							it = dstoreFiles.keySet().iterator();
+							it = storeOrder.iterator();
 						}
 						//If indexed dstore does not have the file, add it to its requireIndex entry
 						Integer thisStore = it.next();
@@ -534,7 +554,7 @@ public class Controller {
 					//Dstores not chosen in the above loop must have an entry added to removeIndex, if they have the file
 					for(int j=0; j<(requireIndex.size() - rFactor); j++) {
 						if(it == null || !it.hasNext()) {
-							it = dstoreFiles.keySet().iterator();
+							it = storeOrder.iterator();
 						}
 						
 						Integer thisStore = it.next();
@@ -573,6 +593,7 @@ public class Controller {
 								}
 							}
 						}
+						if(fileMessage.equals("")) continue;
 						fileMessage = file + " " + (fileMessage.trim().split(" ").length) + fileMessage;
 						sendMessages.add(fileMessage);
 					}
@@ -603,9 +624,9 @@ public class Controller {
 								}
 							}
 						}
-						catch(NullPointerException e) {
+						catch(DstoreDisconnectException e) {
 							e.printStackTrace();
-							//removeDstore(thisStore);
+							removeDstore(thisStore);
 						}
 					}).start();
 				}
@@ -666,9 +687,7 @@ public class Controller {
 			for(String file : list) {
 				if(!index.containsKey(file)) {
 					//Log error
-					//return; //Throw exception?
-					//Ignore those, there might be new resources a joining Dstore wants to contribute
-					//Then again, there might be malformed messages. Think about this.
+					return; //Throw exception?
 				}
 				toList.add(file);
 			}
@@ -692,11 +711,13 @@ public class Controller {
 		}
 	}
 	
-	List<Integer> reshuffle(Collection<Integer> col) {
-		List<Integer> list = new ArrayList<Integer>();
-		for(Integer i : col) {
-			list.add(0, i);
+	<T> List<T> reshuffle(Collection<T> col) {
+		List<T> list = new ArrayList<T>();
+		Iterator<T> it = col.iterator();
+		while(it.hasNext()) {
+			list.add(it.next());
 		}
+		Collections.shuffle(list);
 		return list;
 	}
 	
diff --git a/Dstore.class b/Dstore.class
index 5a496f658f3927ece60f8eebab9b968dd8e10c43..ff1e5b46bfd884be9e7581f53b80d4c57d1bce07 100644
GIT binary patch
delta 5959
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

delta 5683
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

diff --git a/Dstore.java b/Dstore.java
index 9332ba9..f9c6770 100644
--- a/Dstore.java
+++ b/Dstore.java
@@ -35,7 +35,7 @@ public class Dstore {
 		
 		fileSizes = new HashMap<String,Long>();
 		for(File file : fileFolder.listFiles()) {
-			fileSizes.put(file.getName(), Long.valueOf(file.length()));
+			if(!file.delete()) throw new Exception("Directory specified has undeletable files; please try a different directory");
 		}
 	}
 	
@@ -247,7 +247,11 @@ public class Dstore {
 			String[] filesToRemove;
 			int index;
 			
-			System.out.println("Interpreting message...");
+			String tmessage = "";
+			for(String s : message) {
+				tmessage = tmessage + " " + s;
+			}
+			System.out.println("Interpreting message:" + tmessage);
 			int numberToSend = Integer.parseInt(message[1]);
 			index = 2;
 			filesToSend = new HashMap<Integer,List<String>>();
diff --git a/DstoreConnection$ReceiveContext.class b/DstoreConnection$ReceiveContext.class
new file mode 100644
index 0000000000000000000000000000000000000000..29a6f8871a554ee11deeab64ee52990e0810f08f
GIT binary patch
literal 3277
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

literal 0
HcmV?d00001

diff --git a/DstoreConnection.class b/DstoreConnection.class
index 4cd5bbd5bd6e2a239616b6ab9228d2a0898566e7..78bdda2b66cc70e62e1b5a96c7af9d389228ec03 100644
GIT binary patch
delta 2341
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
YL5P8gp_74wVJ`y<!#;)s42Kvb0ekBFWdHyG

delta 2034
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

diff --git a/DstoreConnection.java b/DstoreConnection.java
index bdd3bc1..4778e99 100644
--- a/DstoreConnection.java
+++ b/DstoreConnection.java
@@ -15,9 +15,11 @@ public class DstoreConnection {
 	protected PrintWriter writer;
 	protected boolean available;
 	protected List<String> queue;
+	protected int timeout;
 	
-	public DstoreConnection(Socket socket) {
+	public DstoreConnection(Socket socket, int timeout) {
 		this.socket = socket;
+		this.timeout = timeout;
 		try {
 			reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
 			writer = new PrintWriter(socket.getOutputStream());
@@ -34,7 +36,7 @@ public class DstoreConnection {
 		}
 	}
 	
-	public String sendAndReceive(String message, String expectedMessage) throws NullPointerException {
+	public String sendAndReceive(String message, String expectedMessage) throws DstoreDisconnectException {
 		System.out.println("Getting lock...");
 		synchronized(this) {
 			try {
@@ -48,16 +50,16 @@ public class DstoreConnection {
 			catch(NullPointerException e) {
 				System.out.println("Dstore disconnected");
 				available = false;
-				throw new NullPointerException();
+				throw new DstoreDisconnectException();
 			}
 		}
 	}
 	
-	public String sendAndReceive(String message) throws NullPointerException {
+	public String sendAndReceive(String message) throws DstoreDisconnectException {
 		return sendAndReceive(message, null);
 	}
 	
-	public String receive(String expectedMessage) throws NullPointerException {
+	public String receive(String expectedMessage) throws DstoreDisconnectException {
 		System.out.println("Getting lock...");
 		synchronized(this) {
 			System.out.println("Lock acquired");
@@ -76,19 +78,34 @@ public class DstoreConnection {
 		}
 	}
 	
-	public String receive() throws NullPointerException {
+	public String receive() throws DstoreDisconnectException {
 		return receive(null);
 	}
 	
-	protected String localReceive(String expectedMessage) throws NullPointerException {
+	protected String localReceive(String expectedMessage) throws DstoreDisconnectException {
 		try {
+			ReceiveContext rc = new ReceiveContext(expectedMessage);
+			synchronized(rc.lock) {
+				rc.start();
+				rc.lock.wait(timeout);
+				rc.end();
+			}
+			String returnMessage = rc.getReturnMessage();
+			if(returnMessage == null) throw new DstoreDisconnectException();
+			else return returnMessage;
+		}
+		catch(InterruptedException e) {
+			e.printStackTrace();
+		}
+			
+			/*
 			String returnMessage = null;
 			do {
 				returnMessage = reader.readLine();
 				if(returnMessage == null) {
 					System.out.println("Dstore disconnected");
 					available = false;
-					throw new NullPointerException();
+					throw new DstoreDisconnectException();
 				}
 				if(expectedMessage != null && !expectedMessage.equals(returnMessage.split(" ")[0])) {
 					queue.add(returnMessage);
@@ -104,5 +121,69 @@ public class DstoreConnection {
 			e.printStackTrace();
 			return "";
 		}
+		*/
+		return "";
+	}
+	
+	//Seperate class for enabling timeouts while receiving messages
+	protected class ReceiveContext {
+		protected String expectedMessage;
+		protected String returnMessage;
+		protected Thread thread;
+		public Object lock;
+		
+		public ReceiveContext(String expectedMessage) {
+			this.expectedMessage = expectedMessage;
+			returnMessage = "";
+			lock = new Object();
+		}
+		
+		public String getReturnMessage() {
+			synchronized(lock) {
+				return returnMessage;
+			}
+		}
+		
+		public void start() {
+			thread = new Thread(() -> {
+				try {
+					String message = null;
+					do {
+						message = reader.readLine();
+						if(message == null) {
+							System.out.println("Dstore disconnected");
+							available = false;
+							throw new DstoreDisconnectException();
+						}
+						if(expectedMessage != null && !expectedMessage.equals(message.split(" ")[0])) {
+							queue.add(message);
+							if(queue.size() > MAX_QUEUE_SIZE) queue.remove(0);
+							message = null;
+						}
+					}
+					while(message == null);
+					System.out.println("Controller received " + message);
+					returnMessage = message;
+				}
+				catch(IOException e) {
+					e.printStackTrace();
+					returnMessage = "";
+				}
+				catch(DstoreDisconnectException e) {
+					e.printStackTrace();
+					returnMessage = null;
+				}
+				finally {
+					synchronized(lock) {
+						lock.notify();
+					}
+				}
+			});
+			thread.start();
+		}
+		
+		public void end() {
+			if(thread.isAlive()) thread.interrupt();
+		}
 	}
 }
diff --git a/DstoreDisconnectException.class b/DstoreDisconnectException.class
new file mode 100644
index 0000000000000000000000000000000000000000..f1a70dafe9f2cfe9e9879cbf5b4fc17a31599470
GIT binary patch
literal 291
zcmX^0Z`VEs1_mnz0S*QxMg|#|;*$KLRE3PhVuhsC)I5ch%;Mzyyu8%plGGF~1{MZZ
zb_O;c26hGxMh4-m#Ii*FoW#6zeb<WQ)Pj=C{5(bmHk-`6%o00B22l+kgo5CbqRhN>
zYt1lr1};VhNr){jaI=y0GizvuF*2|?=clAHGVuFk=B4_T<|d^Ug(N2Bq%tya1?QI*
zC8xS&f;e(G&Cvr{&7jD@$-u$@0*nld4D1Zt42%ps3=9m)3``7+3=9nHT0)H58JIUR
iFfcGO@G>wka4|43Ffgz(uraVPFf#BlFfcGN@B;vm+C*yr

literal 0
HcmV?d00001

diff --git a/DstoreDisconnectException.java b/DstoreDisconnectException.java
new file mode 100644
index 0000000..085512f
--- /dev/null
+++ b/DstoreDisconnectException.java
@@ -0,0 +1,7 @@
+import java.lang.Throwable;
+
+public class DstoreDisconnectException extends Exception {
+	public DstoreDisconnectException() {
+		super("Dstore has been disconnected");
+	}
+}
diff --git a/downloads/AllStar.txt b/downloads/AllStar.txt
deleted file mode 100644
index 26e7fef..0000000
--- a/downloads/AllStar.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-Somebody once told me the world is gonna roll me
-I ain't the sharpest tool in the shed
-She was looking kind of dumb with her finger and her thumb
-In the shape of an "L" on her forehead
-
-Well, the years start coming and they don't stop coming
-Fed to the rules and I hit the ground running
-Didn't make sense not to live for fun
-Your brain gets smart but your head gets dumb
-
-So much to do, so much to see
-So what's wrong with taking the back streets?
-You'll never know if you don't go
-You'll never shine if you don't glow
-
-Hey, now, you're an all-star, get your game on, go play
-Hey, now, you're a rock star, get the show on, get paid
-And all that glitters is gold
-Only shooting stars break the mold
-
-It's a cool place and they say it gets colder
-You're bundled up now wait 'til you get older
-But the meteor men beg to differ
-Judging by the hole in the satellite picture
-
-The ice we skate is getting pretty thin
-The water's getting warm so you might as well swim
-My world's on fire. How about yours?
-That's the way I like it and I'll never get bored
-
-Hey, now, you're an all-star, get your game on, go play
-Hey, now, you're a rock star, get the show on, get paid
-And all that glitters is gold
-Only shooting stars break the mold
-
-Go for the moon
-Go for the moon
-Go for the moon
-Go for the moon
-
-Hey, now, you're an all-star, get your game on, go play
-Hey, now, you're a rock star, get the show on, get paid
-And all that glitters is gold
-Only shooting stars
-
-Somebody once asked could I spare some change for gas
-I need to get myself away from this place
-I said yep, what a concept
-I could use a little fuel myself
-And we could all use a little change
-
-Well, the years start coming and they don't stop coming
-Fed to the rules and I hit the ground running
-Didn't make sense not to live for fun
-Your brain gets smart but your head gets dumb
-
-So much to do, so much to see
-So what's wrong with taking the back streets?
-You'll never know if you don't go
-You'll never shine if you don't glow
-
-Hey, now, you're an all star, get your game on, go play
-Hey, now, you're a rock star, get the show on, get paid
-And all that glitters is gold
-Only shooting stars break the mold
-
-And all that glitters is gold
-Only shooting stars break the mold
diff --git a/downloads/Grandad.txt b/downloads/Grandad.txt
deleted file mode 100644
index 4891fef..0000000
--- a/downloads/Grandad.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-(Yabba Dabba Doo!)
-
-Flintstones. Meet the Flintstones.
-They're the modern stone age family.
-From the town of Bedrock,
-They're a page right out of history.
-
-Let's ride with the family down the street.
-Through the courtesy of Fred's two feet.
-
-When you're with the Flintstones
-Have a yabba dabba doo time.
-A dabba doo time.
-We'll have a gay old time.
diff --git a/downloads/PumpkinHill.txt b/downloads/PumpkinHill.txt
deleted file mode 100644
index e245805..0000000
--- a/downloads/PumpkinHill.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-You know me, the fighting freak Knuckles,
-And we're at Pumpkin Hill,
-You ready?
-
-I ain't gonna let it get to me, I'm just gonna creep,
-Down in Pumpkin Hill I gots to find my lost piece.
-I know that it's here, I can sense it in my feet,
-The great Emerald's power allows me to feel.
-I can't see a thing but it's around somewhere,
-I'm gonna hold my head 'cause I have no fear.
-This probably seems crazy, crazy, a graveyard theory,
-A ghost tried to approach me and got leery.
-
-Asked him a question and he vanished in a second,
-I'm walkin' through valleys cryin' pumpkin in the alley.
-Didn't seem happy but they sure tried to get me,
-Had to back 'em up with the fist, metal crack 'em.
-I'm hearing someone sayin' "You a chicken, don't be scared!"
-It had to be the wind, 'cause nobody wasn't there.
-I searched and I searched as I climbed up the wall,
-And then I started to fly, I went in deeper!
-
-Let it get to me? I'm just gonna creep,
-Down in Pumpkin Hill I gots to find my lost piece.
-I know that it's here, I sense it in my feet,
-The great Emerald's power allows me to feel.
-I can't see a thing but it's around somewhere,
-I gotta hold my head, I have no fear.
-It probably seems crazy, crazy, a graveyard theory,
-A ghost tried to approach me, he got leery.
-
-(This is Knuckles, who fears none.)
-(It's real deal when it comes to my name, kid!)
-
-I ain't gonna let it get to me, I'm just gonna creep,
-Down in Pumpkin Hill I gots to find my lost piece.
-I know that it's here, I can sense it in my feet,
-The great Emerald's power allows me to feel.
-I can't see a thing but it's around somewhere,
-I'm gonna hold my head 'cause I have no fear.
-This probably seems crazy, crazy, a graveyard theory,
-A ghost tried to approach me and got leery.
-
-Asked him a question and he vanished in a second,
-I'm walkin' through valleys cryin' pumpkin in the alley.
-Didn't seem happy but they sure tried to get me,
-Had to back 'em up with the fist, metal crack 'em.
-I'm hearing someone sayin' "You a chicken, don't be scared!"
-It had to be the wind, 'cause nobody wasn't there.
-I searched and I searched as I climbed up the wall,
-And then I started to fly, I went in deeper!
-
-Let it get to me? I'm just gonna creep,
-Down in Pumpkin Hill I gots to find my lost piece.
-I know that it's here, I sense it in my feet,
-The great Emerald's power allows me to feel.
-I can't see a thing but it's around somewhere,
-I gotta hold my head, I have no fear.
-It probably seems crazy, crazy, a graveyard theory,
-A ghost tried to approach me, he got leery.
-
-(Spooky up in here, it's crazy in here,)
-(We still gon' keep it goin', I'm Knuckles.)
-(Nobody scares me,)
-(Whoever want it, bring it!)
-(I don't care, we 'ka do this.)
-(Then come step up to the plate, and meet your match,)
-(It ain't no thang.)
diff --git a/downloads/SnowHalation.txt b/downloads/SnowHalation.txt
deleted file mode 100644
index 09add47..0000000
--- a/downloads/SnowHalation.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-Fushigi da ne ima no kimochi
-Sora kara futte kita mitai
-Tokubetsu na kisetsu no iro ga tokimeki o miseru yo
-
-Hajimete deatta toki kara
-Yokan ni sawagu kokoro no Melody
-Tomerarenai tomaranai na・ze
-
-Todokete
-Setsunasa ni wa namae o tsukeyou ka "Snow halation"
-Omoi ga kasanaru made matezu ni
-Kuyashii kedo suki tte junjou
-Binetsu no naka tameratte mo dame da ne
-Tobikomu yuuki ni sansei mamonaku Start!!
-
-Oto mo naku kehai mo naku
-Shizuka ni unmei wa kawaru
-Korekara no mirai ni mune no kodou ga hayaku naru
-
-Tatoeba komatta toki ni wa
-Sugu kaketsukete dakishimetakute
-Doko ni ite mo dokodemo Fly high
-
-Isoide
-Itsu no ma ni ka ookiku nari sugita "True emotion"
-Yume dake miteru you ja tsurai yo
-Koibito wa kimi tte iitai
-Yasashii me ga tomadotteru iya da yo
-Kono mama ikki ni aijou azukete Please!!
-
-Todokete
-Setsunasa ni wa namae o tsukeyou ka "Snow halation"
-Omoi ga kasanaru made matezu ni
-Kuyashii kedo suki tte junjou
-Binetsu no naka tameratte mo dame da ne
-Tobikomu yuuki ni sansei mamonaku Start!! 
diff --git a/downloads/Unknown.txt b/downloads/Unknown.txt
deleted file mode 100644
index bc6fa8e..0000000
--- a/downloads/Unknown.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-Here I come, rougher than the rest of them
-The best of them, tougher than leather
-You can call me Knuckles, unlike Sonic I don't chuckle
-I'd rather flex my muscles
-
-I'm hard as nails, it ain't hard to tell
-I break 'em down whether they're solid or frail
-Unlike the rest I'm independent since my first breath
-First test, feel the right, than the worst's left
-
-Born on an island in the heavens
-The blood of my ancestors flows inside me
-My duty is to save the flower
-From evil deterioration
-
-I will be the one to set your heart free, true
-Cleanse yourself of them evil spirits that's in you
-
-Streaking lights, loud sounds, and instincts
-Are the elements that keep me going
-I am fighting my own mission
-Nothing's gonna stand in my way
-
-I will be the one to set your heart free, true
-Cleanse yourself of them evil spirits that's in you
-
-Won't be frightened, I'll stand up to all the pain and turmoil
-Just believe in myself, won't rely on others
-Get this power to wipe out the havoc and anarchy
-This is my planet, gonna fight for my destiny
-
-Here I come, rougher than the rest of them
-The best of them, tougher than leather
-You can call me Knuckles, unlike Sonic I don't chuckle
-I'd rather flex my muscles
-
-I'm hard as nails, it ain't hard to tell
-I break 'em down whether they're solid or frail
-Unlike the rest I'm independent since my first breath
-First test, feel the right, than the worst's left
-
-I have no such things as weak spots
-Don't approve of him but gotta trust him
-This alliance has a purpose
-This partnership is only temporary
-
-I will be the one to set your heart free, true
-Cleanse yourself of evil spirits that got in you
-
-Won't be frightened, I'll stand up to all the pain and turmoil
-Just believe in myself, won't rely on others
-Freedom will be waiting when serenity is restored
-This is my planet, I shall not surrender
-
-Won't be frightened, I'll stand up to all the pain and turmoil
-Just believe in myself, won't rely on others
-Get this power to wipe out the havoc and anarchy
-This is my planet, gonna fight
-
-Won't be frightened, I'll stand up to all the pain and turmoil
-Just believe in myself, won't rely on others
-Freedom will be waiting when serenity is restored
-This is my planet, I shall not surrender
-
-The new porcupine on the block with the buff chest
-In the wilderness with the ruggedness
-Knock, knock, it's Knuckles, the bloat thrower
-Independent flower, Magical Emerald holder
-I'll give you the coldest shoulder
-My spikes go through boulders, that's why I stay a loner
-I was born by myself, I don't need a posse
-I get it on by myself, adversaries get shelved
-
-Right on!
-- 
GitLab