// Path: src/com/metamolecular/mx/model/Atom.java
// public interface Atom
// {
//   public String getSymbol();
//   
//   public void setSymbol(String newSymbol);
//   
//   public int getIndex();
//   
//   public void setIsotope(int isotope);
//   
//   public int getIsotope();
//   
//   public boolean hasSingleIsotope();
//   
//   public void setCharge(int charge);
//   
//   public int getCharge();
//   
//   public void setRadical(int radical);
//   
//   public int getRadical();
//   
//   public Atom[] getNeighbors();
//   
//   public Bond[] getBonds();
//   
//   public Bond getBond(Atom neighbor);
//   
//   public int countNeighbors();
//   
//   public boolean isConnectedTo(Atom atom);
//   
//   public int countVirtualHydrogens();
//   
//   public double getX();
//   
//   public double getY();
//   
//   public double getZ();
//   
//   public void move(double x, double y, double z);
//   
//   public int getValence();
//   
//   public Molecule getMolecule();
// }
// 
// Path: src/com/metamolecular/mx/model/Bond.java
// public interface Bond
// {
//   public int getIndex();
//   
//   public Atom getSource();
//   
//   public Atom getTarget();
//   
//   public Atom getMate(Atom atom);
//   
//   public boolean contains(Atom atom);
//   
//   public void setType(int type);
//   
//   public int getType();
//   
//   public void setStereo(int stereo);
//   
//   public int getStereo();
//   
//   public void reverse();
//   
//   public Molecule getMolecule();
//   
//   public Atom[] getNeighborAtoms();
// }
// 
// Path: src/com/metamolecular/mx/walk/DefaultStep.java
// public class DefaultStep implements Step
// {
//   private Atom focus;
//   private List<Atom> path;
//   private List<Bond> bonds;
// 
//   public DefaultStep(Atom focus)
//   {
//     this.focus = focus;
//     path = new ArrayList();
//     bonds = new ArrayList();
// 
//     loadBonds(null);
//     path.add(focus);
//   }
// 
//   private DefaultStep(DefaultStep step, Bond bond)
//   {
//     this.focus = bond.getMate(step.getAtom());
//     this.path = new ArrayList(step.path);
//     this.bonds = new ArrayList();
// 
//     path.add(focus);    
//     loadBonds(bond);
//   }
// 
//   public Atom getAtom()
//   {
//     return focus;
//   }
// 
//   public List<Atom> getPath()
//   {
//     return path;
//   }
// 
//   public boolean hasNextBond()
//   {
//     return bonds.size() != 0;
//   }
// 
//   public Bond nextBond()
//   {
//     Bond result = null;
//     
//     try
//     {
//       result = bonds.remove(bonds.size() - 1);
//     }
//     
//     catch (ArrayIndexOutOfBoundsException e)
//     {
//       throw new RuntimeException("Attempt to get nonexistant bond.", e);
//     }
//     
//     return result;
//   }
// 
//   public Step nextStep(Bond bond)
//   {
//     return new DefaultStep(this, bond);
//   }
// 
//   public boolean closesRingWith(Bond bond)
//   {
//     Atom mate = bond.getMate(focus);
//     
//     return path.contains(mate);
//   }
// 
//   private void loadBonds(Bond exclude)
//   {
//     for (Bond bond : focus.getBonds())
//     {
//       if (bond != exclude)
//       {
//         bonds.add(bond);
//       }
//     }
//   }
// }
// 
// Path: src/com/metamolecular/mx/walk/Step.java
// public interface Step
// {
//   public Atom getAtom();
//   
//   public List<Atom> getPath();
//   
//   public boolean hasNextBond();
//   
//   public Step nextStep(Bond bond);
//   
//   public Bond nextBond();
//   
//   public boolean closesRingWith(Bond bond);
// }


import java.util.Arrays;
import junit.framework.TestCase;
import static org.mockito.Mockito.*;
import com.metamolecular.mx.model.Atom;
import com.metamolecular.mx.model.Bond;
import com.metamolecular.mx.walk.DefaultStep;
import com.metamolecular.mx.walk.Step;
    Atom mate = mock(Atom.class);
    Bond[] mateBonds = new Bond[]
    {
    };
    when(mate.getBonds()).thenReturn(mateBonds);
    when(bond.getMate(atom)).thenReturn(mate);

    Step nextStep = step.nextStep(step.nextBond());

    assertEquals(mate, nextStep.getAtom());
  }

  public void testItAddsNewAtomToPathOfNextStep()
  {
    atomWithOneBond();
    Atom mate = mock(Atom.class);
    Bond[] mateBonds = new Bond[]
    {
    };
    when(mate.getBonds()).thenReturn(mateBonds);
    when(bond.getMate(atom)).thenReturn(mate);

    Step nextStep = step.nextStep(step.nextBond());

    assertEquals(Arrays.asList(atom, mate), nextStep.getPath());
  }

  public void testItExcludesConnectingBondFromBondsOfNewStep()
  {
    atomWithOneBond();
// Path: src/com/metamolecular/mx/model/Atom.java
// public interface Atom
// {
//   public String getSymbol();
//   
//   public void setSymbol(String newSymbol);
//   
//   public int getIndex();
//   
//   public void setIsotope(int isotope);
//   
//   public int getIsotope();
//   
//   public boolean hasSingleIsotope();
//   
//   public void setCharge(int charge);
//   
//   public int getCharge();
//   
//   public void setRadical(int radical);
//   
//   public int getRadical();
//   
//   public Atom[] getNeighbors();
//   
//   public Bond[] getBonds();
//   
//   public Bond getBond(Atom neighbor);
//   
//   public int countNeighbors();
//   
//   public boolean isConnectedTo(Atom atom);
//   
//   public int countVirtualHydrogens();
//   
//   public double getX();
//   
//   public double getY();
//   
//   public double getZ();
//   
//   public void move(double x, double y, double z);
//   
//   public int getValence();
//   
//   public Molecule getMolecule();
// }
// 
// Path: src/com/metamolecular/mx/model/Bond.java
// public interface Bond
// {
//   public int getIndex();
//   
//   public Atom getSource();
//   
//   public Atom getTarget();
//   
//   public Atom getMate(Atom atom);
//   
//   public boolean contains(Atom atom);
//   
//   public void setType(int type);
//   
//   public int getType();
//   
//   public void setStereo(int stereo);
//   
//   public int getStereo();
//   
//   public void reverse();
//   
//   public Molecule getMolecule();
//   
//   public Atom[] getNeighborAtoms();
// }
// 
// Path: src/com/metamolecular/mx/walk/DefaultStep.java
// public class DefaultStep implements Step
// {
//   private Atom focus;
//   private List<Atom> path;
//   private List<Bond> bonds;
// 
//   public DefaultStep(Atom focus)
//   {
//     this.focus = focus;
//     path = new ArrayList();
//     bonds = new ArrayList();
// 
//     loadBonds(null);
//     path.add(focus);
//   }
// 
//   private DefaultStep(DefaultStep step, Bond bond)
//   {
//     this.focus = bond.getMate(step.getAtom());
//     this.path = new ArrayList(step.path);
//     this.bonds = new ArrayList();
// 
//     path.add(focus);    
//     loadBonds(bond);
//   }
// 
//   public Atom getAtom()
//   {
//     return focus;
//   }
// 
//   public List<Atom> getPath()
//   {
//     return path;
//   }
// 
//   public boolean hasNextBond()
//   {
//     return bonds.size() != 0;
//   }
// 
//   public Bond nextBond()
//   {
//     Bond result = null;
//     
//     try
//     {
//       result = bonds.remove(bonds.size() - 1);
//     }
//     
//     catch (ArrayIndexOutOfBoundsException e)
//     {
//       throw new RuntimeException("Attempt to get nonexistant bond.", e);
//     }
//     
//     return result;
//   }
// 
//   public Step nextStep(Bond bond)
//   {
//     return new DefaultStep(this, bond);
//   }
// 
//   public boolean closesRingWith(Bond bond)
//   {
//     Atom mate = bond.getMate(focus);
//     
//     return path.contains(mate);
//   }
// 
//   private void loadBonds(Bond exclude)
//   {
//     for (Bond bond : focus.getBonds())
//     {
//       if (bond != exclude)
//       {
//         bonds.add(bond);
//       }
//     }
//   }
// }
// 
// Path: src/com/metamolecular/mx/walk/Step.java
// public interface Step
// {
//   public Atom getAtom();
//   
//   public List<Atom> getPath();
//   
//   public boolean hasNextBond();
//   
//   public Step nextStep(Bond bond);
//   
//   public Bond nextBond();
//   
//   public boolean closesRingWith(Bond bond);
// }


// Path: src/com/metamolecular/mx/test/DefaultStepTest.java
import java.util.Arrays;
import junit.framework.TestCase;
import static org.mockito.Mockito.*;
import com.metamolecular.mx.model.Atom;
import com.metamolecular.mx.model.Bond;
import com.metamolecular.mx.walk.DefaultStep;
import com.metamolecular.mx.walk.Step;

    Atom mate = mock(Atom.class);
    Bond[] mateBonds = new Bond[]
    {
    };
    when(mate.getBonds()).thenReturn(mateBonds);
    when(bond.getMate(atom)).thenReturn(mate);

    Step nextStep = step.nextStep(step.nextBond());

    assertEquals(mate, nextStep.getAtom());
  }

  public void testItAddsNewAtomToPathOfNextStep()
  {
    atomWithOneBond();
    Atom mate = mock(Atom.class);
    Bond[] mateBonds = new Bond[]
    {
    };
    when(mate.getBonds()).thenReturn(mateBonds);
    when(bond.getMate(atom)).thenReturn(mate);

    Step nextStep = step.nextStep(step.nextBond());

    assertEquals(Arrays.asList(atom, mate), nextStep.getPath());
  }

  public void testItExcludesConnectingBondFromBondsOfNewStep()
  {
    atomWithOneBond();
    Atom mate = mock(Atom.class);