Index: trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Interfaces/IRealVectorParticleUpdater.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Interfaces/IRealVectorParticleUpdater.cs	(revision 5566)
+++ trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Interfaces/IRealVectorParticleUpdater.cs	(revision 5568)
@@ -31,5 +31,5 @@
     ILookupParameter<DoubleMatrix> BoundsParameter { get; }
     ILookupParameter<RealVector> PersonalBestParameter { get; }
-    ILookupParameter<RealVector> NeighborsBestParameter { get; }
+    ILookupParameter<RealVector> NeighborBestParameter { get; }
   }
 }
Index: trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Interfaces/IRealVectorSwarmUpdater.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Interfaces/IRealVectorSwarmUpdater.cs	(revision 5566)
+++ trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Interfaces/IRealVectorSwarmUpdater.cs	(revision 5568)
@@ -25,5 +25,5 @@
 namespace HeuristicLab.Encodings.RealVectorEncoding {
   public interface IRealVectorSwarmUpdater : ISwarmUpdater, IRealVectorOperator {
-    IScopeTreeLookupParameter<RealVector> NeighborsBestParameter { get; }
+    IScopeTreeLookupParameter<RealVector> NeighborBestParameter { get; }
     IScopeTreeLookupParameter<RealVector> PersonalBestParameter { get; }
     IScopeTreeLookupParameter<RealVector> RealVectorParameter { get; }
Index: trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorNeighborhoodParticleUpdater.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorNeighborhoodParticleUpdater.cs	(revision 5566)
+++ trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorNeighborhoodParticleUpdater.cs	(revision 5568)
@@ -22,7 +22,6 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Encodings.RealVectorEncoding {
@@ -47,10 +46,10 @@
       double omega = Inertia.Value;
       double phi_p = PersonalBestAttraction.Value;
-      double phi_g = NeighborsBestAttraction.Value;
+      double phi_g = NeighborBestAttraction.Value;
       for (int i = 0; i < velocity.Length; i++) {
         velocity[i] =
           Velocity[i] * omega +
           (PersonalBest[i] - RealVector[i]) * phi_p * r_p +
-          (NeighborsBest[i] - RealVector[i]) * phi_g * r_g;
+          (BestPoint[i] - RealVector[i]) * phi_g * r_g;
       }
       BoundsChecker.Apply(velocity, VelocityBounds);
Index: trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorParticleUpdater.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorParticleUpdater.cs	(revision 5566)
+++ trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorParticleUpdater.cs	(revision 5568)
@@ -45,6 +45,9 @@
       get { return (ILookupParameter<RealVector>)Parameters["PersonalBest"]; }
     }
-    public ILookupParameter<RealVector> NeighborsBestParameter {
-      get { return (ILookupParameter<RealVector>)Parameters["NeighborsBest"]; }
+    public ILookupParameter<RealVector> NeighborBestParameter {
+      get { return (ILookupParameter<RealVector>)Parameters["NeighborBest"]; }
+    }
+    public LookupParameter<RealVector> BestPointParameter {
+      get { return (LookupParameter<RealVector>)Parameters["BestPoint"]; }
     }
     public ILookupParameter<RealVector> RealVectorParameter {
@@ -63,6 +66,6 @@
       get { return (ILookupParameter<DoubleValue>)Parameters["PersonalBestAttraction"]; }
     }
-    public ILookupParameter<DoubleValue> NeighborsBestAttractionParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["NeighborsBestAttraction"]; }
+    public ILookupParameter<DoubleValue> NeighborBestAttractionParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["NeighborBestAttraction"]; }
     }
     #endregion
@@ -79,10 +82,13 @@
       get { return PersonalBestParameter.ActualValue; }
     }
+    protected RealVector BestPoint {
+      get { return BestPointParameter.ActualValue; }
+    }
     protected RealVector RealVector {
       get { return RealVectorParameter.ActualValue; }
       set { RealVectorParameter.ActualValue = value; }
     }
-    protected RealVector NeighborsBest {
-      get { return NeighborsBestParameter.ActualValue; }
+    protected RealVector NeighborBest {
+      get { return NeighborBestParameter.ActualValue; }
     }
     protected DoubleMatrix Bounds {
@@ -98,6 +104,6 @@
       get { return PersonalBestAttractionParameter.ActualValue; }
     }
-    protected DoubleValue NeighborsBestAttraction {
-      get { return NeighborsBestAttractionParameter.ActualValue; }
+    protected DoubleValue NeighborBestAttraction {
+      get { return NeighborBestAttractionParameter.ActualValue; }
     }
     #endregion
@@ -108,5 +114,5 @@
     protected RealVectorParticleUpdater(bool deserializing) : base(deserializing) { }
     protected RealVectorParticleUpdater(RealVectorParticleUpdater original, Cloner cloner) : base(original, cloner) { }
-    
+
     public RealVectorParticleUpdater()
       : base() {
@@ -116,10 +122,10 @@
       Parameters.Add(new LookupParameter<RealVector>("PersonalBest", "Particle's personal best solution."));
       Parameters.Add(new LookupParameter<RealVector>("BestPoint", "Global best position."));
-      Parameters.Add(new LookupParameter<RealVector>("NeighborsBest", "Best neighboring solution."));
+      Parameters.Add(new LookupParameter<RealVector>("NeighborBest", "Best neighboring solution."));
       Parameters.Add(new LookupParameter<DoubleMatrix>("Bounds", "The lower and upper bounds for each dimension of the position vector for the current problem."));
       Parameters.Add(new LookupParameter<DoubleMatrix>("VelocityBounds", "Upper and lower bounds for the particle's velocity vector."));
       Parameters.Add(new LookupParameter<DoubleValue>("Inertia", "The weight for the particle's velocity vector."));
       Parameters.Add(new LookupParameter<DoubleValue>("PersonalBestAttraction", "The weight for the particle's personal best position."));
-      Parameters.Add(new LookupParameter<DoubleValue>("NeighborsBestAttraction", "The weight for the global best position."));
+      Parameters.Add(new LookupParameter<DoubleValue>("NeighborBestAttraction", "The weight for the global best position."));
     }
 
Index: trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorSwarmUpdater.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorSwarmUpdater.cs	(revision 5566)
+++ trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorSwarmUpdater.cs	(revision 5568)
@@ -25,4 +25,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -43,6 +44,6 @@
       get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["PersonalBestQuality"]; }
     }
-    public IScopeTreeLookupParameter<DoubleValue> NeighborsBestQualityParameter {
-      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["NeighborsBestQuality"]; }
+    public IScopeTreeLookupParameter<DoubleValue> NeighborBestQualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["NeighborBestQuality"]; }
     }
     public IScopeTreeLookupParameter<RealVector> RealVectorParameter {
@@ -52,9 +53,9 @@
       get { return (IScopeTreeLookupParameter<RealVector>)Parameters["PersonalBest"]; }
     }
-    public IScopeTreeLookupParameter<RealVector> NeighborsBestParameter {
-      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["NeighborsBest"]; }
-    }
-    public IValueLookupParameter<BoolValue> MaximizationParameter {
-      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    public IScopeTreeLookupParameter<RealVector> NeighborBestParameter {
+      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["NeighborBest"]; }
+    }
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
     }
     public ILookupParameter<DoubleValue> BestQualityParameter {
@@ -66,4 +67,10 @@
     public IScopeTreeLookupParameter<IntArray> NeighborsParameter {
       get { return (IScopeTreeLookupParameter<IntArray>)Parameters["Neighbors"]; }
+    }
+    public ValueLookupParameter<IDiscreteDoubleMatrixModifier> VelocityBoundsUpdaterParameter {
+      get { return (ValueLookupParameter<IDiscreteDoubleMatrixModifier>)Parameters["VelocityBoundsUpdater"]; }
+    }
+    public LookupParameter<DoubleMatrix> VelocityBoundsParameter {
+      get { return (LookupParameter<DoubleMatrix>)Parameters["VelocityBounds"]; }
     }
     #endregion
@@ -82,7 +89,9 @@
     private ItemArray<DoubleValue> PersonalBestQuality {
       get { return PersonalBestQualityParameter.ActualValue; }
-    }
-    private ItemArray<DoubleValue> NeighborsBestQuality {
-      get { return NeighborsBestQualityParameter.ActualValue; }
+      set { PersonalBestQualityParameter.ActualValue = value; }
+    }
+    private ItemArray<DoubleValue> NeighborBestQuality {
+      get { return NeighborBestQualityParameter.ActualValue; }
+      set { NeighborBestQualityParameter.ActualValue = value; }
     }
     private ItemArray<RealVector> RealVector {
@@ -93,7 +102,7 @@
       set { PersonalBestParameter.ActualValue = value; }
     }
-    private ItemArray<RealVector> NeighborsBest {
-      get { return NeighborsBestParameter.ActualValue; }
-      set { NeighborsBestParameter.ActualValue = value; }
+    private ItemArray<RealVector> NeighborBest {
+      get { return NeighborBestParameter.ActualValue; }
+      set { NeighborBestParameter.ActualValue = value; }
     }
     private bool Maximization {
@@ -102,4 +111,11 @@
     private ItemArray<IntArray> Neighbors {
       get { return NeighborsParameter.ActualValue; }
+    }
+    private IDiscreteDoubleMatrixModifier VelocityBoundsUpdater {
+      get { return VelocityBoundsUpdaterParameter.ActualValue; }
+    }
+    private DoubleMatrix VelocityBounds {
+      get { return VelocityBoundsParameter.ActualValue; }
+      set { VelocityBoundsParameter.ActualValue = value; }
     }
     #endregion
@@ -116,10 +132,12 @@
       Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "Particle's quality"));
       Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("PersonalBestQuality", "Particle's personal best quality"));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("NeighborsBestQuality", "Global best particle quality"));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("NeighborBestQuality", "Global best particle quality"));
       Parameters.Add(new ScopeTreeLookupParameter<RealVector>("RealVector", "Particle's position"));
       Parameters.Add(new ScopeTreeLookupParameter<RealVector>("PersonalBest", "Particle's personal best position"));
-      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("NeighborsBest", "Neighborhood (or global in case of totally connected neighborhood) best particle position"));
+      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("NeighborBest", "Neighborhood (or global in case of totally connected neighborhood) best particle position"));
       Parameters.Add(new ScopeTreeLookupParameter<IntArray>("Neighbors", "The list of neighbors for each particle."));
-      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
+      Parameters.Add(new ValueLookupParameter<IDiscreteDoubleMatrixModifier>("VelocityBoundsUpdater", "Modifies the velocity bounds in the course of optimization."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("VelocityBounds", "Maximum velocity for each dimension."));
     }
 
@@ -132,8 +150,14 @@
     public override IOperation Apply() {
       InitializeBestPoint();
+      UpdateNeighbors();
       UpdateSwarm();
-      UpdateNeighbors();
-      UpdateVelocityBounds();
-      return base.Apply();
+      if (VelocityBoundsUpdater != null) {
+        var ops = new OperationCollection();
+        ops.Add(ExecutionContext.CreateChildOperation(VelocityBoundsUpdater));
+        ops.Add(ExecutionContext.CreateOperation(Successor));
+        return ops;
+      } else {
+        return base.Apply();
+      }
     }
 
@@ -148,47 +172,23 @@
     private void UpdateNeighbors() {
       if (Neighbors != null & Neighbors.Length > 0) {
-        if (this.NeighborsBest == null || NeighborsBest.Length != Neighbors.Length)
-          NeighborsBest = new ItemArray<RealVector>(Neighbors.Length);
+        if (this.NeighborBest == null || NeighborBest.Length != Neighbors.Length)
+          NeighborBest = new ItemArray<RealVector>(Neighbors.Length);
         for (int n = 0; n < Neighbors.Length; n++) {
           var pairs = Quality.Zip(RealVector, (q, p) => new { Quality = q, Point = p })
             .Where((p, i) => i == n || Neighbors[n].Contains(i));
-          NeighborsBest[n] = Maximization ?
+          NeighborBest[n] = Maximization ?
           pairs.OrderByDescending(p => p.Quality.Value).First().Point :
           pairs.OrderBy(p => p.Quality.Value).First().Point;
         }
-        NeighborsBestParameter.ActualValue = NeighborsBest;
-      }
-    }
-
-    private void UpdateVelocityBounds() {
-      // ToDo: Add code
+        NeighborBestParameter.ActualValue = NeighborBest;
+      }
     }
 
     private void UpdateSwarm() {
       if (PersonalBestQuality.Length == 0) {
-        ItemArray<DoubleValue> personalBestQualities = new ItemArray<DoubleValue>(RealVector.Length);
-        for (int i = 0; i < RealVector.Length; i++) {
-          if (Maximization) {
-            personalBestQualities[i] = new DoubleValue(double.MinValue);
-          } else {
-            personalBestQualities[i] = new DoubleValue(double.MaxValue);
-          }
-        }
-        PersonalBestQualityParameter.ActualValue = personalBestQualities;
-      }
-      if (NeighborsBestQuality.Length == 0) {
-        if (NeighborsParameter != null && Neighbors.Length > 0) {
-          ItemArray<DoubleValue> neighborsBestQualities = new ItemArray<DoubleValue>(RealVector.Length);
-          for (int i = 0; i < RealVector.Length; i++) {
-            if (Maximization) {
-              neighborsBestQualities[i] = new DoubleValue(double.MinValue);
-            } else {
-              neighborsBestQualities[i] = new DoubleValue(double.MaxValue);
-            }
-          }
-          NeighborsBestQualityParameter.ActualValue = neighborsBestQualities;
-        }
-      }
-      ItemArray<RealVector> neighborsBest = new ItemArray<RealVector>(RealVector.Length);
+        PersonalBestQuality = (ItemArray<DoubleValue>)Quality.Clone();
+        if (VelocityBounds == null)
+          VelocityBounds = new DoubleMatrix(new double[,] { { -1, 1 } });
+      }
       for (int i = 0; i < RealVector.Length; i++) {
         if (Maximization && Quality[i].Value > PersonalBestQuality[i].Value ||
@@ -196,16 +196,24 @@
           PersonalBestQuality[i].Value = Quality[i].Value;
           PersonalBest[i] = RealVector[i];
-          if (Maximization && PersonalBestQuality[i].Value > NeighborsBestQuality[i].Value ||
-             !Maximization && PersonalBestQuality[i].Value < NeighborsBestQuality[i].Value) {
-            NeighborsBestQuality[i].Value = PersonalBestQuality[i].Value;
-            neighborsBest[i] = PersonalBest[i];
+        }
+      }
+      if (Neighbors.Length > 0) {
+        var neighborBestQuality = NeighborBestQuality;
+        var neighborBest = NeighborBest;
+        if (NeighborBestQuality.Length == 0) {
+          neighborBestQuality = (ItemArray<DoubleValue>)Quality.Clone();
+          neighborBest = (ItemArray<RealVector>)RealVector.Clone();
+        }
+        for (int i = 0; i < RealVector.Length; i++) {
+          if (Maximization && PersonalBestQuality[i].Value > NeighborBestQuality[i].Value ||
+             !Maximization && PersonalBestQuality[i].Value < NeighborBestQuality[i].Value) {
+            neighborBestQuality[i].Value = PersonalBestQuality[i].Value;
+            neighborBest[i] = PersonalBest[i];
           }
         }
-      }
-      if (NeighborsParameter != null && Neighbors.Length > 0) {
-        NeighborsBestParameter.ActualValue = neighborsBest;
-      }
-    }
-
+        NeighborBestQuality = neighborBestQuality;
+        NeighborBest = neighborBest;
+      }
+    }
   }
 }
Index: trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorTotallyConnectedParticleUpdater.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorTotallyConnectedParticleUpdater.cs	(revision 5566)
+++ trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorTotallyConnectedParticleUpdater.cs	(revision 5568)
@@ -22,6 +22,6 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Encodings.RealVectorEncoding {
@@ -51,10 +51,10 @@
       double omega = Inertia.Value;
       double phi_p = PersonalBestAttraction.Value;
-      double phi_g = NeighborsBestAttraction.Value;
+      double phi_g = NeighborBestAttraction.Value;
       for (int i = 0; i < velocity.Length; i++) {
         velocity[i] =
           Velocity[i] * omega +
           (PersonalBest[i] - RealVector[i]) * phi_p * r_p +
-          (NeighborsBest[i] - RealVector[i]) * phi_g * r_g;
+          (BestPoint[i] - RealVector[i]) * phi_g * r_g;
       }
       BoundsChecker.Apply(velocity, VelocityBounds);
